上次我们介绍了“函数上下文”this指向问题中两个规则
①1.2 规则 1 :直接圆括号执行,上下文是 window 对象
②1.2 规则 2 :从对象中调用或者数组中枚举执行的函数,上下文是这个对象或者数
组
下面我们继续介绍关于this指向的一些其它问题:
1.3 规则 3 :定时器直接调用,上下文是 window 对象
var a = 100;
function fun() {
console.log(this.a)
}
setInterval(fun, 1000);
需要注意的是定时器调用和定时器函数内部调用是有区别的;
下面代码是定时器在调用 obj.fun 函数,所以调用者是定时器
var obj = {
a: 300,
fun: function() {
console.log(this.a++)
}
}
var a = 100;
setInterval(obj.fun, 1000)
下面的代码本质是 obj 在调用函数,所以上下文是 obj;
var obj = {
a: 300,
fun: function() {
console.log(this.a++)
}
}
var a = 100;
setInterval(function() {
obj.fun()
}, 1000)
1.4 规则 4 : DOM 事件中的 this ,指的是触发事件的这个 DOM 元素
var box1 = document.getElementById('box1');
var box2 = document.getElementById('box2');
var box3 = document.getElementById('box3');
var box4 = document.getElementById('box4');
function changeColor() {
this.style.backgroundColor = 'purple'
}
box1.onclick = changeColor;
box2.onclick = changeColor;
box3.onclick = changeColor;
box4.onclick = changeColor;
此时点击的元素变为紫色
1.5 规则 5 : call()和 和 apply()可以设置函数的上下文
函数的上下文主要是看谁在调用,但是我们可以通过 call()和 apply()去设置函数的上下文。
call()和 apply()本质就是调用函数的同时,指定上下文
比如我们有一个 changeSex 的函数,它的作用是修改 sex 的属性。
此时有一个 xiaohong 对象,sex 为女
此时我们调用这个 changeSex 函数,强行将函数的上下文绑定为 xiaohong
function changeSex() {
if (this.sex == '男') {
this.sex = '女'
} else {
this.sex = '男'
}
console.log(this)
}
var xiaohong = {
name: '小红',
sex: '女'
}
changeSex.call(xiaohong)
alert(xiaohong.sex)
此时小红对象被修改为了男
apply 函数也有同样的功能
changeSex.apply(xiaohong)
规范
函数.call(带有上下文内容)
函数.call(带有上下文内容)
函数的上下文就是带有上下文的内容
需要注意的是 call()和 apply()的本质核心是有区别的:主要是语法上的区别,call 是接受参数,apply 是接受数组
call 方法要求,所有的参数在上下文对象后面一一罗列
function person(name, age, height, weight) {
this.name = name;
this.age = age;
this.height = height;
this.weight = weight
}
var xiaoming = {
name: '小明',
age: 3,
height: 60,
weight: 15
}
person.call(xiaoming, '小明', 23, 183, 65)
此时我们换成 apply,apply 要求所有的参数必须规整到一个数组中
person.apply(xiaoming, ['小明', 30, 183, 75])
apply 本质上只要求两个参数,第二个参数是一个数组集合
在使用结果上两种方式都是一样的
●小题目
function fun1() {
fun2.apply(obj, arguments)
}
function fun2(a, b, c) {
console.log(obj)
console.log(a)
console.log(b)
console.log(c)
}
var obj = {
name: '小明',
sex: '男'
}
fun1("香蕉", '葡萄', '梨子')
此时你会发现 apply 有一个功能是将第二个参数将数组进行结构,变成一个个的罗列参数,比如我们传进
arguments 是一个类数组对象,但是我们在 fun2 函数接受的 a,b,c 形参中给进行了解构,也就是分别变成了
香蕉、葡萄、梨子
●小题目
此时我们想根据 apply 的特点出一个思考题,利用 Math 方法进行数组的最大值查找
Math.max.apply(null, [789, 2342, 123, 2134, 2345, 22])
我们知道 apply 第二个参数是数组,但是 apply 有能力给解构,所以,我们可以利用这个特点求数组的最大或者最小值