一、this的隐式绑定
函数this的指向,是在函数调用的时候来确定其指向的
有以下代码,直接调用函数
function aa() {
console.log(this)
}
aa()
输出的this是window,因为aa是window的方法,相当于是window调用了该方法。
再看以下代码,在对象里定义方法
var o = {
a:1,
b:function() {
console.log(this)
}
}
o.b()
执行结果就是“o”这个对象,因为是o调用了b()方法
再看以下代码,请问输出的是什么
var o = {
a:1,
b:function() {
function c () {
console.log(this)
}
c()
}
}
o.b()
答案是window,因为c函数只不过是在b里面执行罢了,并不是o对象的属性,不存在o对象调用了c函数,所以c的指向还是window。
再看以下代码,请问输出的是什么
var o = {
a:1,
b:function() {
console.log(this)
}
}
var f = o.b;
f()
答案是:window,因为o是引用类型(复杂类型),js的引用类型不在栈伤储存,而是在堆上储存,赋给f的只是一个引用地址,相当于将o.b函数指向了变量f,所以还是相当于window直接调用了函数。
上述情况也叫做隐式丢失,将函数赋值给变量,再调用的时候,this指向就回到了window里
再看以下代码,使用new关键字创建新的对象
function aa () {
this.name = 'xiaoli';
console.log(this)
}
new aa()
输出结果为
因为new关键字改变了this的指向,使其指向新new出来的这个对象
同样还有自执行函数的指向也是window,闭包的函数指向也是window
二、this的显示绑定
call()、apply()、bind()函数,用来改变函数this的指向
- call和apply的第一个参数都是传入的要指向的this对象,第二个参数有所区别,call传入的参数为单个形式,apply为数组形式。
- bind和call类似, call调用后立即执行,但bind 返回的是一个新的函数,你必须调用它才会被执行,即需要手动使用()进行调用
使用如下
var obj1 = {
name:"小王",
say:function (age,sex) {
console.log('我的名字叫'+ this.name + '年龄' + age + '性别' + sex)
}
};
var obj2 = {
name: "小白"
};
obj1.say.call(obj2,13,'女');
obj1.say.apply(obj2,[12,'男']);
obj1.say.call(obj2,16,'男');
三、严格模式下this的指向