第一种指向关系:
如果函数做为方法在全局时,this指向则默认绑定
在非严格模式下,this指向的是全局对象window
在严格模式下,this指向是undefined
// 例1
// 在采用var声明的时候,浏览器默认编译的ES5语法,是非严格模式
var data = {
a:1,
b:2,
c:3
}
function name() {
console.log(this.data.a); // 1
return this.data.a+this.data.b+this.data.c
}
name();
// 例2
// 采用const或let声明的时候,浏览器默认ES6语法,则处于严格模式
// 严格模式下this指向是绑定在undefined上的
const data = {
a:1,
b:2,
c:3
}
function name() {
console.log(this.data.a); // undefined
return this.data.a+this.data.b+this.data.c
}
console.log(name());
第二种指向关系:
如果函数是在某个上下文对象中调用,this指向的就是那个上下文的对象
这就是典型的隐式绑定,当函数引用有上下文对象时,this都会被隐式绑定
到当前这个上下文对象
// 例1
const age = {
a:100,
fn1:function () {
console.log(this.a);
}
}
age.fn1(); // 100
// 例2
function name() {
console.log(this.a);
}
/*
出现undefined的原因是age这个对象还未对函数进行引用,隐式绑定未绑定到
这个age上下文对象,this的对象指向还是全局对象window
*/
console.log(name()); // undefined
const age = {
a:100,
fn1:name
}
age.fn1(); // 100
第三种指向关系:
如果函数是在new中调用时,this指向的就是new的那个对象
const name = new fn(1);
new fn = function(a) {
console.log(this); // fn
this.b = a+1;
console.log(this.b); // 2
return this.b;
}
第四种指向关系
如果做为一个函数的方法调用函数,那么this指向就需要分情况讨论了
/*
情况一、匿名函数调用
声明即调用,this指向依旧是window对象
*/
(function () {
console.log(this);
})()
/*
情况二、call、apply函数调用
典型的显式绑定,this指向绑定的中指定的对象
在JavaScript中apply和call传入的第一个参数都是指定的this值,它们的区别在于第二个参数,
apply的第二个参数传入的值是一个数组或对象
call的第二个参数传入的值可以是多个数组或对象
*/
const a ={
name : "heyuanpeng",
fn : function (x,y) {
console.log(this.name); // heyuanpeng
console.log( x+y) // 3
}
}
const b = a.fn;
b.apply(a,[1,2])
b.call(a,1,2)
注意:
在我们上面这么多实例中,会发现大体的一个规则就是this 永远指向最后调用它的那个对象
如何去改变一个this的指向呢
方法一、使用箭头函数
箭头函数的this始终指向函数定义时的 this,而非执行时
方法二、在函数内部使用that=this
方法三、使用call、apply、bind方法传入指定的this对象
网友评论