this指向
普通函数 this 指向 window
构造函数 this 指向 实例化对象
事件中 this 指向 事件源
定时器中 this 指向 window
立即执行函数 this 指向 window
对象方法中的 this 指向 对象本身
原型对象中的 this 指向 实例化对象
call方法改变this指向
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
var num = 10;
function fun(a, b) {
console.log(this);
// 普通函数 this 指向 window
console.log(this.num + a + b);
}
var obj = {
num: 20
}
fun(1, 2);
// Function.prototype.call()
// call() 改变this 指向,参数以 逗号 分割,会立即调用函数执行
fun.call(obj, 1, 2);
</script>
</body>
</html>
apply方法改变this指向
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
var num = 10;
function fun(a, b) {
console.log(this);
// 普通函数 this 指向 window
console.log(this.num + a + b);
}
var obj = {
num: 20
}
fun(1, 2);
// Function.prototype.apply();
// apply() 改变this 指向,参数以数组形式传递,立即调用函数执行
fun.apply(obj, [1, 2]);
</script>
</body>
</html>
bind方法改变this指向
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
var num = 10;
function fun(a, b) {
console.log(this);
// 普通函数 this 指向 window
console.log(this.num + a + b);
}
var obj = {
num: 20
}
fun(1, 2);
// Function.prototype.bind()
// bind() 改变 this 指向,参数以逗号隔开,不会立即调用函数执行,需要手动调用
fun.bind(obj, 1, 2)();
// call() apply() bind()
// 相同点:都可以改变 this 指向
// 不同点:call() apply()之间,都会立即调用函数执行,call()的参数以逗号分隔,apply()的参数以数组形式传递
// call() bind()之间,参数都以逗号分割,call()会立即调用函数执行,bind()需要手动调用
</script>
</body>
</html>
call的使用场景
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
// 数据类型的判断
// 最精准的判断方法
// Object.prototype.toString.call();
var obj = {};
var arr = [];
var date = new Date();
var num = 10;
console.log(Object.prototype.toString.call(obj)); // "[object Object]"
console.log(Object.prototype.toString.call(arr)); // "[object Array]"
console.log(Object.prototype.toString.call(date)); // "[object Date]"
console.log(Object.prototype.toString.call(num)); // "[object Number]"
</script>
</body>
</html>
apply使用场景
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
// apply() 参数以数组形式传递,立即调用函数执行
// Math.max() 传入参数的最大值
console.log(Math.max(2, 3, 5, 7, 1, 7, 9, 0, 4, 7));
var arr = [1, 2, 3, 4, 5, 6, 7, 8, 9];
// 求数组中的最大值最小值
console.log(Math.min.apply(Math, arr));
</script>
</body>
</html>
bind使用场景
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<button>点击</button>
<button>点击</button>
<button>点击</button>
<button>点击</button>
<button>点击</button>
<script>
// bind() 不会立即调用函数执行,一般用于改变定时器中的this 指向
// 循环绑定事件
var btn = document.querySelectorAll("button");
for (var i = 0; i < btn.length; i++) {
btn[i].onclick = function () {
var time = 5;
this.disabled = true;
this.innerHTML = "请" + time + "s之后再次点击";
this.timeId = setInterval(function () {
console.log(this);
if (time > 1) {
time--;
// this
this.innerHTML = "请" + time + "s之后再次点击";
} else {
// this
this.removeAttribute("disabled");
this.innerHTML = "点击";
clearInterval(this.timeId)
}
}.bind(this), 1000)
}
}
</script>
</body>
</html>
constructor判断数据类型
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
var num = 10;
// console.log(num.constructor);
console.log(num.constructor == Number);
var arr = [];
console.log(arr.constructor == Array);
// null undefined 不能用constructor判断数据类型
// 判断数据类型的方法
// typeof instanceof Object.prototype.toString.call() constructor
</script>
</body>
</html>
构造函数继承
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
// 父构造函数
function Father(money) {
this.money = money;
}
// 子构造函数
function Son(name, money) {
this.name = name;
// call() 改变this指向
Father.call(this, money);
}
// 构造函数继承
var son1 = new Son("zhangsan", 2000);
console.log(son1);
</script>
</body>
</html>
原型对象继承
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
// 父构造函数
function Father(money) {
this.money = money;
}
Father.prototype.car = "小米su7";
// 子构造函数
function Son(name, money) {
this.name = name;
// call() 改变this指向
Father.call(this, money);
}
// Son.prototype = Father.prototype 不可取
// 子构造函数的原型 = 父构造函数的实例化
Son.prototype = new Father();
// Son.prototype.car 相当于访问实例化对象的car
// 注意要把构造函数改回来
Son.prototype.constructor = Son;
// 构造函数继承
var son1 = new Son("zhangsan", 2000);
console.log(son1);
console.log(son1.car);
</script>
</body>
</html>
create继承
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
// Object.create() 继承
var father = {
money: 200
}
var son = Object.create(father, {
name: {
enumerable: true,
writable: true,
configurable: true,
value: "小明"
}
});
console.log(son);
</script>
</body>
</html>
数组的操作方法
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
var arr = [1, 1, 2, 3, 4, 5, 6, 7, 8, 9];
// 1.forEach() 遍历数组
arr.forEach(function (value, index, arr) {
// 遍历的元素
console.log(value);
// 索引
console.log(index);
console.log(arr);
});
// 2.map() 遍历数组
var newArr = arr.map(function (value, index, arr) {
// return返回值
return value + "map";
});
console.log(newArr);
// 3.filter() 过滤数组
var newArr = arr.filter(function (value, index, arr) {
return value % 2 == 0;
});
console.log(newArr);
var data = ["小米14", "iphone 15", "小米12", "huawei Mate60", "huawei P60"];
var huawei = data.filter(function (value, index, arr) {
return value.includes("huawei")
});
console.log(huawei);
// 4.some() 数组中是否有满足条件的元素 true false; 一旦发现满足条件的元素,后面的将不再被遍历
var res = arr.some(function (value, index, arr) {
console.log(value);
return value > 5;
});
console.log(res);
// 5.every() 数组中每个元素是否都符合条件; 一旦发现不满足条件的元素,后面的将不再被遍历
var res = arr.every(function (value, index, arr) {
console.log(value);
return value < 5;
});
console.log(res);
// 6.find() 找一个满足条件的值; 一旦找到符合条件的元素,立即返回,后面不再遍历;找不到返回 undefined
var res = arr.find(function (value, index, arr) {
console.log(value);
return value > 5;
});
console.log(res);
// 7.reduce() 累加器 total作为上次操作的结果
var sum = arr.reduce(function (total, value, index, arr) {
console.log(total);
return total + value;
},0)
console.log(sum);
// 数组去重
var resArr = arr.reduce(function (total, value) {
console.log(total);
if (total.includes(value)) {
return total;
} else {
total.push(value);
return total;
}
}, []);
console.log(resArr);
// 数组元素累乘
var res = arr.reduce(function (total, value) {
return total * value;
}, 1);
console.log(res);
</script>
</body>
</html>