<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
// 1、call():调用函数,并改变 this 指向
var obj = {
name: '食喰梦子'
}
function fn1(num1, num2) {
console.log(this);
console.log(num1 + num2);
}
// fn1(1, 2) // this指向 windows
// fn1.call(obj, 1, 2) // this 指向 obj 对象
// * call()应用场景:继承。
// 父构造函数
function Father(uname, age, sex) {
this.uname = uname
this.age = age
this.sex = sex
}
// 子构造函数
function Son(uname, age, sex) {
// 根据谁调用this指向谁的原则,这里调用了 Son 构造函数,所以这里this指向Son
Father.call(this, uname, age, sex)
}
var a = new Son('食喰梦子', 18, '女')
// console.log(a);
// new 了构造函数后,this做了这个几件事
// 首先,构造函数必须通过 new 进行调用
// 调用了构造函数后,就会在内存中创建一个新的空对象
// this 会指向这个空对象
// 执行构造函数内部的代码,为新对象添加属性和方法
// 返回新对象,因此构造函数中不需要使用return
// 2、apply():调用函数,并改变 this 指向
// 注意参数必须是数组格式的
var obj2 = {
name: '五十岚清华'
}
function fn2(arr) {
console.log(this);
console.log(arr);
}
// fn2([1]) // this 指向 Windows
// fn2.apply(obj2, [12]) // this 指向 obj2
// * apply()应用场景:结合Math求最大值和最小值。
// 最小值
// var min = Math.min(-1,-2)
// console.log(min); // -2
var arr = [1,2,3]
// 最大值
// 注: Math.max() 括号里面直接填数字,所以这里通过扩展运算符去除掉了[]
// var max = Math.max(...arr)
// 通过 apply 改变 this 的指向,但是这里我们依然让 this 指向 Math
// apply接受的参数必须是数组形式,所以这里直接将数组arr传递进去
var max = Math.max.apply(Math, arr) // 个人认为因为有了扩展运算符,这种方法反而多余了。
// console.log(max); // 3
// 3、bind():改变this的指向,但是不会调用函数
var obj3 = {
name: '皇伊月'
}
function fn3(num1, num2) {
console.log(this);
console.log(num2 - num1);
}
// fn3(1,2) // this 指向 windows
var f = fn3.bind(obj3, 2, 5)
// 因为bind不会调用函数,所以这里声明一个 f 变量,再调用 f 变量
// bind返回的是原函数改变this之后产生的新函数
f() // this 指向 obj3
// bind()应用场景:在面向对象的编程思想中,经常会需要改变this的指向,但是又不能调用函数。
</script>
</body>
</html>
<!--
总结:
一、相同点:改变this指向。
二、不同点:
1、call()接受的参数形式是:aru1, aru2。 -> 应用场景:继承。
2、apply()接受的参数形式是:[aru1, aru2]。 -> 应用场景:跟数组有关,如求最大值,最小值。
3、call() 和 apply() 都可以调用函数,但 bind()不会调用函数。 -> 应用场景:需要改变this的指向,但是又不想调用函数。
-->