JavaScript中的this、apply()、call()、bind()

this

this是函数执行时基于函数的执行环境绑定的,指向最后调用它的那个对象。

例1:

function a(){
    var name= "Carol";
    console.log(this.user); //undefined
    console.log(this); //Window
}
a();

最后一个调用a的是全局对象Window,因此a的this指向Window,this.name会输出undefined。

例2:

 var a = {
  name: "Carol",
  fn : function () {
   console.log(this.name);  // Carol
  }
 }
 a.fn();

这里最后一个调用fn的是对象a,所以fn中的this指向a,this.name会输出Carol。

例3:

 var a = {
  name: "Carol",
  fn : function () {
   console.log(this.name);  // Carol
  }
 }
 window.a.fn();

这里与上面同样,因为this指向的是最后调用它的那个对象,在这里还是a。

例4:

var a = {
 name : null,
 // name: "Carol",
 fn : function () {
  console.log(this.name);  // undefined
 }
}
var f = a.fn;
f();

这里fn的this仍然是指向window的。
因为虽然fn被赋给了变量f,但是并没有执行,所以fn的this并不是指向a的,最后f是在window里执行的,所以fn的this还是指向window。

例5:

function fn()  
{  
    this.name = 'Carol';  
    return function(){};
}
var a = new fn;  
console.log(a.name); //undefined

以及

function fn()  
{  
    this.name = 'Carol';  
    return 1;
}
var a = new fn;  
console.log(a.name); //Carol

如果返回值是一个对象(除null外),那么this指向的就是那个返回的对象,如果返回值不是一个对象那么this还是指向函数的实例。

如何改变this的指向

使用ES6的箭头函数
箭头函数中没有this绑定,必须通过查找作用域链来决定其值,如果箭头函数被非箭头函数包含,则this绑定的是最近一层非箭头函数的 this,否则,this为undefined。

用局部变量代替this指针
在函数内部写上var _this=this;
用_this来代替this使用。

apply()
apply()接受两个参数,第一个参数是要绑定给this的值,第二个参数是一个参数数组。如果第一个参数是null、undefined的话,this指向window。

var obj = {
    message: 'My name is: '
}

function getName(firstName, lastName) {
    console.log(this.message + firstName + ' ' + lastName)
}

getName.apply(obj, ['Carol', 'Lee'])// My name is: Carol Lee

call()
call()和apply()的作用一样,都可以改变this的指向,只不过接受参数的方式不同。

var obj = {
    message: 'My name is: '
}
function getName(firstName, lastName) {
    console.log(this.message + firstName + ' ' + lastName)
}

getName.apply(obj,'Carol','Lee')// My name is: Carol Lee

bind()
bind()和上面两种略有不同。apply()和call()都是立即执行的,而bind()返回的是一个待执行的函数,便于需要稍后再调用的情况。

var obj = {
    name: 'Carol'
}

function printName() {
    console.log(this.name)
}

var c = printName.bind(obj)
console.log(c)  //function() { … }
c()   //Carol

也就是bind()();才是执行改变。

猜你喜欢

转载自blog.csdn.net/lixinyi0622/article/details/84594300