为什么我们要使用this:使函数可以自动引用合适的上下文对象
关于this的两个误区:
1.this指向函数自身,
2.this指向他的作用域(在某些情况下它是对的,在某些情况下它是错的)
需要注意的是this在任何情况下都不指向函数的词法作用域(词法作用域:一个变量和函数的词法作用域取决于该变量和函数声明的地方)。
this实际上是在函数被调用时所发生的绑定,它指向什么完全取决于函数在哪里调用
以下是总结的一些绑定规则:
当无法适从其他规则时,是this的默认规则
function bar(){ console.log(this.a); } var a = 2; bar();//2
函数调用时,应用了this的默认绑定,this指向了全局变量。为什么this指向了全局?
该函数的调用位置可以理解为在全局调用,所以this指向了全局。当然,如果使用了严格模式,全局对象将无法使用默认绑定,bar()报错。
应用前提:调用位置是否有上下文对象,或者说是否被某个对象拥有或者包含
例如:
function foo() { console.log( this.a ); } var obj = { a: 2, foo: foo }; obj.foo(); // 2
此时的foo()的调用位置实际上是在obj内部,所以this指向了obj
对象属性引用链中只有最顶层或者说最后一层会影响调用位置
function bar(){ console.log( this.a ) }; var obj2 = { a:42, bar:bar } var obj1 = { a: 2, obj2:obj2 } obj1.obj2.bar(); //42,指向obj2
需要注意的是,被隐式绑定的函数在某些情况下会丢失绑定对象,也就是说它会应用默认绑定
function foo() { console.log( this.a ); } var obj = { a: 2, foo: foo }; var bar = obj.foo; // 函数别名! var a = "oops, global"; // a 是全局对象的属性 bar(); // "oops, global"
function foo() { console.log( this.a ); } function doFoo(fn) { // fn 其实引用的是 foo fn(); // <-- 调用位置! } var obj = { a: 2, foo: foo }; var a = "oops, global"; // a 是全局对象的属性 doFoo( obj.foo ); // "oops, global"
可以使用函数的apply(..)和call(..)方法,强制绑定this的值
例如:
function foo() { console.log( this.a ); } var obj = { a:2 }; foo.call( obj ); // 2
A.call(B)或者A.apply(B) 临时绑定,对于this绑定来说,他们没有不同。
其他方面的应用,他们有所不同,例如:
A.call(B,1000,2000,3000):用B调用A函数,并将其后的值传入A函数中
A.apply(B,arr):用B调用A函数,并将arr数组内的值传入A函数中,自动打散数组为单个值
同时,还有一个bind(),也可以用来进行绑定。
bind()不同于apply(),call()的地方在于:bind是永久绑定,其返回了一个修改后的函数,让对应的函数想什么时候调就什么时候调用,并且可以将参数在执行的时候添加。
例如:
var a = { user:"追梦子", fn:function(){ console.log(this.user); //追梦子 } } var b = a.fn; b.bind(a);//并没有执行, var c = b.bind(a); console.log(c); // function() { [native code] } c(); //此时执行,
首先我们要知道,使用new来构造函数时发生了什么:
所以其第三步就可以进行this的绑定,例如:
function bar(a){ this.a = a; } var b = new bar(2); console.log(b.a); // 2
所以我们可以根据以下来判断this的绑定:
1.函数是否在new中调用(new绑定),如果是的话,this绑定的是新创建的对象
var bar = new foo();
2.函数是否通过apply()或call()显示绑定,如果是的话,this绑定的是指定的对象
var bar = foo.call(obj2);
3.函数是否在某个上下文对象中调用(隐式绑定),如果是的话,this绑定的是那个上下文对象
var bar = obj1.foo();
4.如果都不是的话,使用默认绑定,如果在严格模式下,就绑定到undefined,否则绑定到全局对象
var bar = foo();
但是,凡是都有例外,对于箭头函数来说,我们不能根据以上四点来判断this的绑定,
箭头函数中,this是根据外层(函数或者全局)作用域来决定的。
例如:
function foo() { // 返回一个箭头函数 return (a) => { //this 继承自 foo() console.log( this.a ); }; } var obj1 = { a:2 }; var obj2 = { a:3 }; var bar = foo.call( obj1 ); bar.call( obj2 ); // 2, 不是 3 !
function Person (name,age){ this.name = name; this.age = age; setInterval(()=>{ console.log("I‘m " + this.name + " and I‘m " + this.age +" years old"); },100) } var lilei = Person(‘LiLei‘,20);//I‘m LiLei and I‘m 20 years old
this指向的是Person对象
原文:https://www.cnblogs.com/whaleAlice/p/11945913.html