const arr = [1,2,3];
console.log('数组中存在2:', arr.includes(2)); // true,includes:存在就返回true,不存在就返回false
console.log('数组中存在2:', (arr.indexOf(2) >= 0)); // true,indexOf:从数组第0个位置开始,查找数组中第一个出现该元素的位置,存在就返回该元素在数据中的索引下标,不存在就返回-1
console.log('数组中存在22:', arr.includes(22)); // false,includes:存在就返回true,不存在就返回false
console.log('数组中存在22:', (arr.indexOf(22) >= 0)); // false,indexOf:从数组第0个位置开始,查找数组中第一个出现该元素的位置,存在就返回该元素在数据中的索引下标,不存在就返回-1
// 执行结果:
数组中存在2: true
数组中存在2: true
数组中存在22: false
数组中存在22: false
(1)、利用ES6中的Set对象去重
const arr = [1,2,2,3,3,4,4];
const arr2 = [...new Set(arr)]; // 使用ES6的Set对象对数组进行去重,再使用拓展运算符将结果转化成数组
const arr3 = Array.from(new Set(arr)); // 使用Array.from将结果转化为数组
console.log("使用ES6的Set对象对数组进行去重,再使用拓展运算符将结果转化成数组:", arr2);
console.log("使用ES6的Set对象对数组进行去重,再使用Array.from将结果转化为数组", arr3);
// 执行结果:
使用ES6的Set对象对数组进行去重,再使用拓展运算符将结果转化成数组: (4) [1, 2, 3, 4]
使用ES6的Set对象对数组进行去重,再使用Array.from将结果转化为数组 (4) [1, 2, 3, 4]
(2)、利用filter+indexOf函数去重
const arr = [1,2,2,3,3,4,4];
const arr3 = arr.filter((item, index) => arr.indexOf(item, 0) === index); // 使用filter进行过滤,利用indexOf从当前数据第0个元素开始查找,判断该元素是否第一次出现,如果是,那么就判断是否等于当前索引下标。
console.log("利用filter+indexOf函数去重:", arr3);
// 执行结果:
利用filter+indexOf函数去重: (4) [1, 2, 3, 4]
const arr1 = [1,2,3];
const arr2 = [4,5,6];
const arr3 = arr1.concat(arr2);
const arr4 = [...arr1, ...arr2];
console.log("使用concat函数合并:", arr3);
console.log("使用拓展运算符合并:", arr4);
// 执行结果:
使用concat函数合并: (6) [1, 2, 3, 4, 5, 6]
使用拓展运算符合并: (6) [1, 2, 3, 4, 5, 6]
const map = {"Name": "lala", "Sex": "男", "Phone": "1101110110", "Salary": 100};
const list = [map];
console.log("处理前数据:" , list);
list.map(data => {
data.Name = "拉拉";
data.AnnualSalary = 12 * data.Salary;
});// map函数会处理改动原来数据中的元素,最终返回结果还是一个数组
console.log("处理后数据:" , list);
// 执行结果:
处理前数据: [{…}]0: {Name: 'lala', Sex: '男', Phone: '1101110110', Salary: 100, AnnualSalary: 1200}length: 1[[Prototype]]: Array(0)
处理后数据: [{…}]0: {Name: '拉拉', Sex: '男', Phone: '1101110110', Salary: 100, AnnualSalary: 1200}length: 1[[Prototype]]: Array(0)
使用 window.alert() 弹出警告框。
使用 document.write() 方法将内容写到 HTML 文档中。
使用 innerHTML 写入到 HTML 元素。
使用 console.log() 写入到浏览器的控制台。
// 根据标签ID处理标签内容
document.getElementById("pp").innerHTML = "你好";
// 根据标签tag处理标签,得到的是一个数组
document.getElementsByTagName("p")[1].innerHTML = "你说";
// 异常处理
try {
console.info("开始执行try块语句 ---> ")
console.info("还没有发生例外 ---> ")
throw new Error("发生意外了");
} catch(err) {
console.error("捕捉到例外,开始执行catch块语句 --->");
console.error("错误名称: " + err.name+" ---> ");
console.error("错误信息: " + err.message+" ---> ");
} finally {
console.info("开始执行finally块语句")
}
let x = "";
const d = new Date().getDay();
switch (d)
{
case 0:x="今天是星期日";
break;
case 1:x="今天是星期一";
break;
case 2:x="今天是星期二";
break;
case 3:x="今天是星期三";
break;
case 4:x="今天是星期四";
break;
case 5:x="今天是星期五";
break;
case 6:x="今天是星期六";
break;
}
console.log(x);
// 执行结果:
今天是星期一
JavaScript 支持不同类型的循环:
for - 循环代码块一定的次数
for/in - 循环遍历对象的属性
while - 当指定的条件为 true 时循环指定的代码块
do/while - 同样当指定的条件为 true 时循环指定的代码块
const arr = [1, 2, 3];
// fori循环
for (let i = 0; i < arr.length; i++) {
console.log("fori循环:", arr[i]);
}
// 数组的forin循环
for (index in arr) {
console.log("数组的forin循环:", arr[index]);
}
const person = {"name": "lala", "age": 12};
// map或者object的forin循环
for (key in person) {
console.log("map或者object的forin循环", key, ":", person[key]);
}
let i = 0;
// while循环
while (i < arr.length) {
console.log("while循环:", arr[i]);
i++;
}
let i1 = 0;
// dowhile循环
do {
console.log("dowhile循环:", arr[i1]);
i1++;
} while (i1 < arr.length);
// forEach循环
arr.forEach((item, index) => console.log("forEach循环:", item));
// 执行结果:
fori循环: 1
fori循环: 2
fori循环: 3
数组的forin循环: 1
数组的forin循环: 2
数组的forin循环: 3
map或者object的forin循环 name : lala
map或者object的forin循环 age : 12
while循环: 1
while循环: 2
while循环: 3
dowhile循环: 1
dowhile循环: 2
dowhile循环: 3
forEach循环: 1
forEach循环: 2
forEach循环: 3
const arr = ["Hello","Word","!"];
console.log("原数组内容:", arr);
console.log("使用join函数合并数组之后:", arr.join(""));
// 执行结果:
原数组内容: (3) ['Hello', 'Word', '!']
使用join函数合并数组之后: HelloWord!
// console.time开启并运行一个计时器:XXX接口调用花费时间
console.time("XXX接口调用花费时间");
// 中间业务逻辑,模拟XXX接口调用
console.log("XXX接口调用成功");
XXX接口调用成功
// 接口调用成功后,打印接口调用耗时
console.timeLog("XXX接口调用花费时间");
XXX接口调用花费时间: 64269.987060546875 ms
// 最后关闭计时器
console.timeEnd("XXX接口调用花费时间");
XXX接口调用花费时间: 85647.34912109375 ms
值类型(基本类型):字符串(String)、数字(Number)、布尔(Boolean)、空(Null)、未定义(Undefined)、Symbol。
const a = "a";
const a1 = new String("a");
const b = 1;
const b1 = new Number(1);
const c;
const d = true;
const d1 = new Boolean(true);
console.log("a的数据类型为:", typeof(a), " a的值为:", a);
console.log("a1的数据类型为:", typeof(a1), " a1的值为:", a1);
console.log("b的数据类型为:", typeof(b), " b1的值为:", b);
console.log("b1的数据类型为:", typeof(b1), " b1的值为:", b1);
console.log("c的数据类型为:", typeof(c));
console.log("d的数据类型为:", typeof(d), " d1的值为:", d);
console.log("d1的数据类型为:", typeof(d1), " d1的值为:", d1);
// 执行结果:
a的数据类型为: string a的值为: a
a1的数据类型为: object a1的值为: String {'a'}
b的数据类型为: number b1的值为: 1
b1的数据类型为: object b1的值为: Number {1}
d的数据类型为: boolean d1的值为: true
d1的数据类型为: object d1的值为: Boolean {true}
引用数据类型(对象类型):对象(Object)、数组(Array)、函数(Function),还有两个特殊的对象:正则(RegExp)和日期(Date)。
const u = new Date();
const v = new RegExp(".");
const x = {};
const x1 = new Map();
const y = [];
const y1 = new Array();
const z = null;
const z1 = new Object();
console.log("u的数据类型为:", typeof(u));
console.log("v的数据类型为:", typeof(v));
console.log("x的数据类型为:", typeof(x));
console.log("x1的数据类型为:", typeof(x1));
console.log("y的数据类型为:", typeof(y));
console.log("y1的数据类型为:", typeof(y1));
console.log("z的数据类型为:", typeof(z));
console.log("z1的数据类型为:", typeof(z1));
// 执行结果:
u的数据类型为: object
v的数据类型为: object
x的数据类型为: object
x1的数据类型为: object
y的数据类型为: object
y1的数据类型为: object
z的数据类型为: object
z1的数据类型为: object
const person = {"name": "lala", "age": 12};
person.sex = "男";
const person1 = new Object();
person1.sex = "男";
console.log("person的name属性:", person.name);
console.log("person的name属性:", person["name"]);
console.log("person的sex属性:", person.sex);
console.log("person的sex属性:", person["sex"]);
console.log("person1的sex属性:", person1.sex);
console.log("person1的sex属性:", person1["sex"]);
// 执行结果
person的name属性: lala
person的name属性: lala
person的sex属性: 男
person的sex属性: 男
person1的sex属性: 男
person1的sex属性: 男
function sum (a, b) { // 有参数函数
return a + b; // 带有返回值
}
const result = sum(1, 2);
console.log("调用函数sum返回结果:", result);
// 执行结果:
调用函数sum返回结果: 3
局部变量只作用于函数内,不同的函数可以使用相同名称的变量。
局部变量在函数开始执行时创建,函数执行完后局部变量会自动销毁。
const b = "全局变量";
function variable () {
const a = "局部变量";
const b = "variable全局变量";
return a.concat(b);
}
function variable1 () {
const a = "局部变量";
const b = "variable1全局变量";
return a.concat(b);
}
console.log("b为全局变量,可以在函数内部调用:", variable());
console.log("b为全局变量,可以在函数内部调用:", variable1());
console.log("b为全局变量,可以在外部调用:", b);
console.log("window为全局变量,外部调用任何时候都可以使用,但是window对象没有定义a属性:", window.a);
console.log("a为局部变量,无法在外部调用:", a);
// 执行结果:
b为全局变量,可以在函数内部调用: 局部变量variable全局变量
b为全局变量,可以在函数内部调用: 局部变量variable1全局变量
b为全局变量,可以在外部调用: 全局变量
window为全局变量,外部调用任何时候都可以使用,但是window对象没有定义a属性: undefined
a为局部变量,无法在外部调用: a
13.1、定义
(1)undefined:是所有没有赋值变量的默认值,自动赋值。
(2)null:主动释放一个变量引用的对象,表示一个变量不再指向任何对象地址。
13.2、何时使用null?
当使用完一个比较大的对象时,需要对其进行释放内存时,设置为 null。
13.3、null 与 undefined 的异同点是什么呢?
共同点:都是原始类型,保存在栈中变量本地。
不同点:
(1)undefined——表示变量声明过但并未赋过值。
它是所有未赋值变量默认值,例如:
var a; // a 自动被赋值为 undefined
(2)null——表示一个变量将来可能指向一个对象。
一般用于主动释放指向对象的引用,例如:
var emps = [‘ss’,‘nn’];
emps = null; // 释放指向数组的引用
13.4、垃圾回收站
它是专门释放对象内存的一个程序。
(1)在底层,后台伴随当前程序同时运行;引擎会定时自动调用垃圾回收期;
(2)总有一个对象不再被任何变量引用时,才释放。
JS变量也需要遵循先声明后使用的规定,虽然JS中会存在变量提升的情况,也就是可以先使用后申明。
// 声明的变量才会被提升
x = 55;
console.log(x);
var x;
// 执行结果
x在使用之后申明:55
// 初始化的变量不会被提升
var x = 55;
console.log("x1在之后声明并初始化,不会被提升:", x , x1);
var x1 = 77;
// 执行结果:
x1在之后声明并初始化,不会被提升:55 undefined
var x = 55;
var x1;
console.log("x1在使用之后才初始化,不会被提升:", x , x1);
x1 = 77;
// 执行结果:
x1在之后声明并初始化,不会被提升:55 undefined
面向对象语言中 this 表示当前对象的一个引用。但在 JavaScript 中 this 不是固定不变的,它会随着执行环境的改变而改变。
(1)、 在方法中,this 表示该方法所属的对象。
(2)、 如果单独使用,this 表示全局对象。
(3)、 在函数中,this 表示全局对象。
(4)、 在函数中,在严格模式下,this 是未定义的(undefined)。
(5)、 在事件中,this 表示接收事件的元素。
(6)、 类似 call() 和 apply() 方法可以将 this 引用到任何对象。
(1)、作用域:var定义的变量在块作用域之外可以使用,let和const定义的变量在块作用域之外不可以使用
{
var a = 1; // 块作用域之外可以使用
let b = 2; // 块作用域之外不可以使用
const c = 3;// 块作用域之外不可以使用
}
// 在块作用域之外使用
console.log("块作用域之外可以使用:", a);
console.log("块作用域之外不可以使用,报错b未定义:", b);
console.log("块作用域之外不可以使用,报错c未定义:", c);
// 执行结果:
块作用域之外可以使用: 1
caught ReferenceError: b is not defined
caught ReferenceError: c is not defined
(2)、可改变性:var和let定义的变量可以再次改变值,onst定义的变量不可以再次改变值,再次改变值会报错。
var a = 1;
let b = 2;
const c = 3;
a = 11;
b = 22;
c = 33; // 报错:TypeError: Assignment to constant variable.
console.log("var定义的变量可以再次改变值:", a);
console.log("let定义的变量可以再次改变值:", b);
console.log("const定义的变量不可以再次改变值,再次改变值会报错", c);
// 执行结果:
var定义的变量可以再次改变值: 11
let定义的变量可以再次改变值: 22
const定义的变量不可以再次改变值,再次改变值会报错 3
(3)、变量提升:var定义的变量是有变量提升的,而let和const没有
console.log("var有变量提升作用,相当于在执行这句之前,声明了a:(var a;):", a);
console.log("let,const没有变量提升作用,相当于在执行这句之前,没有b的定义和初始化,会报错:ReferenceError: Cannot access 'b' before initialization:",b,c);
var a = 11;
let b = 22;
const c = 33;
// 执行结果:
var有变量提升作用,相当于在执行这句之前,声明了a:(var a;):undefined
ReferenceError: Cannot access 'b' before initialization
// JS类
class B {
constructor(b) {
this.b = b;
}
get sya() {
console.log("这是B类的方法");
}
// 静态方法
static hello() {
console.log("这是B类的静态方法");
}
}
// 类的继承
class A extends B {
constructor(a) {
super(a);
this.a = a;
}
// setter方法
set setA(x) {
this.a = x;
}
// getter方法
get getA() {
return this.a;
}
}
// 调用
let a = new A("初始化值");
console.log("get方法:", a.getA);
a.setA = "set方法设置值";
console.log("get方法:", a.getA);
a.sya;
B.hello();
// 执行结果:
get方法:初始化值
get方法:set方法设置值
所有浏览器都支持 window 对象。它表示浏览器窗口。所有 JavaScript 全局对象、函数以及变量均自动成为 window 对象的成员。全局变量是 window 对象的属性。全局函数是 window 对象的方法。甚至 HTML DOM 的 document 也是 window 对象的属性之一:
window.confirm("确认要退出吗?");
confirm("确认要退出吗?");
window.alert("确认要退出吗?");
alert("确认要退出吗?");
window.document.getElementById("header");
document.getElementById("header");
// 整个窗口的宽度和高度
var w=window.innerWidth
document.documentElement.clientWidth
document.body.clientWidth;
var h=window.innerHeight
document.documentElement.clientHeight
document.body.clientHeight;
window.open() - 打开新窗口
window.close() - 关闭当前窗口
window.moveTo() - 移动当前窗口
window.resizeTo() - 调整当前窗口的尺寸
setInterval() - 间隔指定的毫秒数不停地执行指定的代码。setTimeout() - 在指定的毫秒数后执行指定代码。
let timeout = setTimeout(() => console.log(Math.random()), 10000);
clearTimeout(timeout); // 清除计时器
let interval = setInterval(() => console.log(Math.random()), 1000);
clearInterval(interval); // 清除计时器
Promise 构造函数是 JavaScript 中用于创建 Promise 对象的内置构造函数。
Promise 构造函数接受一个函数作为参数,该函数是同步的并且会被立即执行,所以我们称之为起始函数。起始函数包含两个参数 resolve 和 reject,分别表示 Promise 成功和失败的状态。
起始函数执行成功时,它应该调用 resolve 函数并传递成功的结果。当起始函数执行失败时,它应该调用 reject 函数并传递失败的原因。
Promise 构造函数返回一个 Promise 对象,该对象具有以下几个方法:
(1)、then:用于处理 Promise 成功状态的回调函数。
(2)、catch:用于处理 Promise 失败状态的回调函数。
(3)、finally:无论 Promise 是成功还是失败,都会执行的回调函数。
const flag = true;
let promise = new Promise((resolve, reject) => {
if (flag) {
resolve("成功了");
} else {
reject("失败了");
}
});
promise
.then((result) => {
console.log(result);
return "返回结果到下一阶段使用。";
})
.then((result) => {
throw result + ": 这不是我想要的结果";
})
.catch((error) => console.log(error))
.finally(() => console.log("最后执行finally逻辑"));
// 执行结果:
成功了
返回结果到下一阶段使用。: 这不是我想要的结果
最后执行finally逻辑