深入理解JavaScript中的this關鍵字

1001200 8年前發布 | 5K 次閱讀 JavaScript開發 JavaScript

this

當函數創建后,this也被創建,它指向該函數所操作的對象。

我們先來創建一個對象:

var zhangsan = {
  living:true,
  age:23,
  gender:'male',
  getGender:function(){return zhangsan.gender;}
};
console.log(zhangsan.getGender()); //'male'

注意在getGender方法中我們使用了zhangsan對象本身。它可以使用this來代替,因為this指向該函數所操作的對象,即zhangsan。

this由上下文決定

傳遞給函數的this的值是由函數被調用時的上下文決定的。

下面例子中myObject的屬性sayFoo指向了sayFoo函數。當在全局的作用域下調用sayFoo函數,this就為window對象。當它被myObject的方法調用時,this就為myObject。

var foo = 'foo';
var myObject = {foo: 'I am myObject.foo'};
var sayFoo = function() {
  console.log(this['foo']);
};
myObject.sayFoo = sayFoo;
myObject.sayFoo(); // 'I am myObject.foo' 
sayFoo(); // 'foo'

很顯然this的值是基于函數調用時的上下文。

嵌套函數中的this

當this出現在嵌套函數中,它就會指向window對象,而不是該函數中的對象。

var myObject = {
  func1:function() {
     console.log(this); //myObject
     var func2=function() {
        console.log(this); //window
        var func3=function() {
           console.log(this); //window
        }();
     }();
  }
};
myObject.func1();

該例中的func2和func3都是嵌套函數,所以this為window。

下面的例子就很容易得出答案了~

var foo = {
  func1:function(bar){
    bar(); //window
    console.log(this);//foo object
  }
};
foo.func1(function(){console.log(this)});

如果我們不想this的值丟失,仍然指向該對象,一般我們會使用變量_this或that來存儲this的值。如:

var myObject = {
  myProperty:'some',
  myMethod:function() {
   var that=this; 
   var helperFunction = function() { 
     console.log(that.myProperty); //'some'
     console.log(this); //window
    }();
  }
}
myObject.myMethod();

修改this的值

this的值通常是由調用函數的上下文決定的,但是你可以通過apply()或者call()方法來重寫它的值。即可以使用其它任意對象來調用一個函數。而這兩個方法唯一不同之處就是參數傳遞方式不同,apply()方法傳遞參數數組,call()方法可以傳遞任意多個參數,下面舉例說明:

var myObject = {};
var myFunction = function(param1, param2) {
  this.foo = param1;
  this.bar = param2;
  console.log(this); //{foo = 'foo', bar = 'bar'}
};
myFunction.call(myObject, 'foo', 'bar'); // 將this設為myObject
//myFunction.apply(myObject, ['foo', 'bar']);
console.log(myObject);//foo = 'foo', bar = 'bar'}

構造函數中的this

當一個函數(構造函數)通過new關鍵字來調用,該函數中的this指向它的實例。

var Person = function(name) {
  this.name = name || 'zhangsan'; // this將指向具體的實例對象
}
var zhangsan = new Person('lisi'); //創建一個Person實例
console.log(zhangsan.name);//'lisi'

下面將調用方式改變下,不使用new:

var Person = function(name) {
  this.name=name||'zhangsan';
}
var lisi = Person('lisi'); //注意沒有使用new
console.log(lisi.name); //報錯,因為zhangsan為undefined
console.log(window.name);//'lisi'

構造函數的原型方法中的this

構造函數的原型方法中的this會指向調用該方法的實例對象:

var Person = function(x){
    if(x){this.fullName = x};
};
Person.prototype.getName = function() {
    return this.fullName; //this為實例對象
}
var zhangsan = new Person('zhangsan');
var lisi = new Person('lisi');
console.log(zhangsan.getName(), lisi.getName());//zhangsan , lisi

//如果該實例沒有fullName屬性,就會從原型鏈中查找 Object.prototype.fullName = 'John'; var john = new Person(); console.log(john.getName());//John</code></pre>

 

來自:http://webexpressor.github.io/JavaScript/2012/10/12/fully-understanding-the-this-keyword.html

 

 本文由用戶 1001200 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!