成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

不再彷徨:完全弄懂JavaScript中的this(譯文總結(jié))

YanceyOfficial / 1510人閱讀

摘要:至于,其只是以數(shù)組的方傳入?yún)?shù),其它部分是一樣的,如下它們也可用于在中的類繼承中,調(diào)用父級構(gòu)造器。間接調(diào)用,調(diào)用了父級構(gòu)造器對比方法和,它倆都立即執(zhí)行了函數(shù),而函數(shù)返回了一個新方法,綁定了預先指定好的,并可以延后調(diào)用。

其實this是一個老生常談的問題了。關(guān)于this的文章非常多,其實我本以為自己早弄明白了它,不過昨天在做項目的過程中,還是出現(xiàn)了一絲疑惑,想到大概之前在JavaScript weekly里收藏待看的一篇詳解this的文章(后有鏈接,也附上了稀土上的中文譯文)和另一篇一位前輩推薦的文章,就把它們看了看,對this的認識確實提升了一些。

JavaScript 中的’this‘是動態(tài)的,它在函數(shù)運行時被確定而非在函數(shù)聲明時被確定。所有的函數(shù)都可以調(diào)用"this",這無關(guān)于該函數(shù)是否屬于某個對象。關(guān)于this,主要有以下四種情況。

1.被當做對象的方法被調(diào)用

如果該函數(shù)是被當做某一個對象的方法,那么該函數(shù)的this指向該對象;

    var john = {
      firstName: "John"
    }
    function func() {
      alert(this.firstName + ": hi!")
    }
    john.sayHi = func
    john.sayHi()  // this = john

這里有一點值得注意,當一個對象的方法被取出來賦值給一個變量時,該方法變?yōu)楹瘮?shù)觸發(fā),this指向window或underfind(嚴格模式)。

2.函數(shù)之內(nèi)調(diào)用

當函數(shù)中有 this,其實就意味著它被當做方法調(diào)用,之間調(diào)用相當于把他當做window對象的方法,this指向window,值得注意的是ES5其實是規(guī)定這種情況this=undefined的,只瀏覽器大多還是按照老的方法執(zhí)行(本人在最新版的Chrome,Safari,F(xiàn)irefox中測試都指向window(201607)),在火狐下使用嚴格模式指向undefined;

    func()
    function func() {
        alert(this) // [object Window] or [object global] or kind of..
    }

為了傳遞this,()之前應該為引用類型,類似于obj.a 或者 obj["a"],不能是別的了。

這里還存在一個小坑,當對象的方法中還存在函數(shù)時,該函數(shù)其實是當做函數(shù)模式觸發(fā),所以其this默認為window(嚴格模式下為undefined)解決辦法是給該函數(shù)綁定this。

var numbers = {  
   numberA: 5,
   numberB: 10,
   sum: function() {
     console.log(this === numbers); // => true
     function calculate() {
       // this is window or undefined in strict mode
       console.log(this === numbers); // => false
       return this.numberA + this.numberB;
     }
     return calculate();
   }
};
numbers.sum(); // => NaN or throws TypeError in strict mode  
var numbers = {  
   numberA: 5,
   numberB: 10,
   sum: function() {
     console.log(this === numbers); // => true
     function calculate() {
       console.log(this === numbers); // => true
       return this.numberA + this.numberB;
     }
     // use .call() method to modify the context
     return calculate.call(this);
   }
};
numbers.sum(); // => 15  
3.在new中調(diào)用

一個引用對象的變量實際上保存了對該對象的引用,也就是說變量實際保存的是對真實數(shù)據(jù)的一個指針。
使用new關(guān)鍵字時this的改變其實有以下幾步:

創(chuàng)建 this = {}.

new執(zhí)行的過程中可能改變this,然后添加屬性和方法;

返回被改變的this.

    function Animal(name) {
        this.name = name
        this.canWalk = true
    }
    var animal = new Animal("beastie")
    alert(animal.name)

需要注意的是如果構(gòu)造函數(shù)返回一個對象,那么this指向返回的那個對象;

    function Animal() {
        this.name = "Mousie";
        this.age = "18";
        return {
            name: "Godzilla"
        } // <-- will be returned
    }

    var animal = new Animal()
    console.log(animal.name) // Godzilla
    console.log(animal.age)//undefined

這里需要注意的是不要忘記使用new,否則不會創(chuàng)建一個新的函數(shù)。而是只是執(zhí)行了函數(shù),相當于函數(shù)調(diào)用,this其實指向window

function Vehicle(type, wheelsCount) {  
  this.type = type;
  this.wheelsCount = wheelsCount;
  return this;
}
// Function invocation
var car = Vehicle("Car", 4);  
car.type;       // => "Car"  
car.wheelsCount // => 4  
car === window  // => true 
4.明確調(diào)用this,使用callapply

這是最具JavaScript特色的地方。
如下代碼:

  func.call(obj, arg1, arg2,...)

第一個參數(shù)將作為this的指代對象,之后的參數(shù)將被作為函數(shù)的參數(shù),解決方法是使用bind。

function Animal(type, legs) {  
  this.type = type;
  this.legs = legs;  
  this.logInfo = function() {
    console.log(this === myCat); // => true
    console.log("The " + this.type + " has " + this.legs + " legs");
  };
}
var myCat = new Animal("Cat", 4);  
// logs "The Cat has 4 legs"
setTimeout(myCat.logInfo.bind(myCat), 1000); 
// setTimeout??
  var john = {
    firstName: "John",
    surname: "Smith"
  }
  function func(a, b) {
    alert( this[a] + " " + this[b] )
  }
  func.call(john, "firstName", "surname")  // "John Smith"

至于apply,其只是以數(shù)組的方傳入?yún)?shù),其它部分是一樣的,如下:

  func.call(john, "firstName", "surname")
  func.apply(john, ["firstName", "surname"])

它們也可用于在 ES5 中的類繼承中,調(diào)用父級構(gòu)造器。

    function Runner(name) {  
      console.log(this instanceof Rabbit); // => true
      this.name = name;  
    }
    function Rabbit(name, countLegs) {  
      console.log(this instanceof Rabbit); // => true
      // 間接調(diào)用,調(diào)用了父級構(gòu)造器
      Runner.call(this, name);
      this.countLegs = countLegs;
    }
    var myRabbit = new Rabbit("White Rabbit", 4);  
    myRabbit; // { name: "White Rabbit", countLegs: 4 }
5..bind()

對比方法 .apply() 和 .call(),它倆都立即執(zhí)行了函數(shù),而 .bind() 函數(shù)返回了一個新方法,綁定了預先指定好的 this ,并可以延后調(diào)用。
.bind() 方法的作用是創(chuàng)建一個新的函數(shù),執(zhí)行時的上下文環(huán)境為 .bind() 傳遞的第一個參數(shù),它允許創(chuàng)建預先設(shè)置好 this 的函數(shù)。

var numbers = {  
  array: [3, 5, 10],
  getNumbers: function() {
    return this.array;    
  }
};
// Create a bound function
var boundGetNumbers = numbers.getNumbers.bind(numbers);  
boundGetNumbers(); // => [3, 5, 10]  
// Extract method from object
var simpleGetNumbers = numbers.getNumbers;  
simpleGetNumbers(); // => undefined or throws an error in strict mode  

使用.bind()時應該注意,.bind() 創(chuàng)建了一個永恒的上下文鏈并不可修改。一個綁定函數(shù)即使使用 .call() 或者 .apply()傳入其他不同的上下文環(huán)境,也不會更改它之前連接的上下文環(huán)境,重新綁定也不會起任何作用。
只有在構(gòu)造器調(diào)用時,綁定函數(shù)可以改變上下文,然而這并不是特別推薦的做法。

6.箭頭函數(shù)

箭頭函數(shù)并不創(chuàng)建它自身執(zhí)行的上下文,使得 this 取決于它在定義時的外部函數(shù)。
箭頭函數(shù)一次綁定上下文后便不可更改,即使使用了上下文更改的方法:

    var numbers = [1, 2];  
    (function() {  
      var get = () => {
        console.log(this === numbers); // => true
        return this;
      };
      console.log(this === numbers); // => true
      get(); // => [1, 2]
      // 箭頭函數(shù)使用 .apply() 和 .call()
      get.call([0]);  // => [1, 2]
      get.apply([0]); // => [1, 2]
      // Bind
      get.bind([0])(); // => [1, 2]
    }).call(numbers);

這是因為箭頭函數(shù)擁有靜態(tài)的上下文環(huán)境,不會因為不同的調(diào)用而改變。因此不要使用箭頭函數(shù)定義方法

function Period (hours, minutes) {  
      this.hours = hours;
      this.minutes = minutes;
    }
    Period.prototype.format = () => {  
      console.log(this === window); // => true
      return this.hours + " hours and " + this.minutes + " minutes";
    };
    var walkPeriod = new Period(2, 30);  
    walkPeriod.format(); // => "undefined hours and undefined minutes" 
參考

Four scents of "this"

Gentle explanation of "this" keyword in JavaScript

JavaScript This 之謎(譯文)

強烈推薦覺得沒弄明白的同學看看上面三篇文章,其中第三篇是第二篇的譯文。如果大家對this還有疑問,也歡迎大家一起討論,交流促進思考,共同進步。

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/86447.html

相關(guān)文章

  • 前端點滴

    摘要:走在前端的大道上持續(xù)更新,最后更新時間年月日從作用域說開去不再彷徨完全弄懂中的譯文總結(jié)你不知道的妙用深入理解之和中的對象拷貝高度自適應的個方法中與區(qū)別中回調(diào)地獄的今生前世細談中的一些設(shè)計模式重溫核心概念和基本用法圖片預加載及插件編寫實例跨域 走在前端的大道上 持續(xù)更新,最后更新時間2017年6月19日 從 JavaScript 作用域說開去 不再彷徨:完全弄懂JavaScript中的...

    CoderDock 評論0 收藏0
  • JavaScript深入淺出

    摘要:理解的函數(shù)基礎(chǔ)要搞好深入淺出原型使用原型模型,雖然這經(jīng)常被當作缺點提及,但是只要善于運用,其實基于原型的繼承模型比傳統(tǒng)的類繼承還要強大。中文指南基本操作指南二繼續(xù)熟悉的幾對方法,包括,,。商業(yè)轉(zhuǎn)載請聯(lián)系作者獲得授權(quán),非商業(yè)轉(zhuǎn)載請注明出處。 怎樣使用 this 因為本人屬于偽前端,因此文中只看懂了 8 成左右,希望能夠給大家?guī)韼椭?...(據(jù)說是阿里的前端妹子寫的) this 的值到底...

    blair 評論0 收藏0
  • 正在失業(yè)中的《課多周刊》(第3期)

    摘要:正在失業(yè)中的課多周刊第期我們的微信公眾號,更多精彩內(nèi)容皆在微信公眾號,歡迎關(guān)注。若有幫助,請把課多周刊推薦給你的朋友,你的支持是我們最大的動力。是一種禍害譯本文淺談了在中關(guān)于的不好之處。淺談超時一運維的排查方式。 正在失業(yè)中的《課多周刊》(第3期) 我們的微信公眾號:fed-talk,更多精彩內(nèi)容皆在微信公眾號,歡迎關(guān)注。 若有幫助,請把 課多周刊 推薦給你的朋友,你的支持是我們最大的...

    robin 評論0 收藏0
  • 正在失業(yè)中的《課多周刊》(第3期)

    摘要:正在失業(yè)中的課多周刊第期我們的微信公眾號,更多精彩內(nèi)容皆在微信公眾號,歡迎關(guān)注。若有幫助,請把課多周刊推薦給你的朋友,你的支持是我們最大的動力。是一種禍害譯本文淺談了在中關(guān)于的不好之處。淺談超時一運維的排查方式。 正在失業(yè)中的《課多周刊》(第3期) 我們的微信公眾號:fed-talk,更多精彩內(nèi)容皆在微信公眾號,歡迎關(guān)注。 若有幫助,請把 課多周刊 推薦給你的朋友,你的支持是我們最大的...

    Joyven 評論0 收藏0

發(fā)表評論

0條評論

YanceyOfficial

|高級講師

TA的文章

閱讀更多
最新活動
閱讀需要支付1元查看
<