国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

理解Javascript方法的調用和“this”

ad6623 / 3309人閱讀

摘要:過去的幾年,我看過很多人對方法的調用滿是迷惑。事實上,這也是說明的作用。這就是方法調用的本質。簡單的方法調用顯然用調用方法非常的麻煩。注意上面的規則同樣適用于的方法調用。成員方法下一個常遇到的調用方法的情況是調用一個對象的方法。

過去的幾年,我看過很多人對javascript方法的調用滿是迷惑。尤其是對方法里的this的語義抱怨頗多。

在我(作者)看來,只要弄清楚了方法的本質,上面的以后自然清晰。事實上,這也是ECMAScript說明的作用。在某種意義上這篇文章是說明文檔的簡寫版,但是核心內容是一致的。

核心本質

首先,我們方法調用的本質是一個方法的call方法[1]。它是如下運作的。

創建一個參數列表(argList),包含了從頭到尾的全部參數

第一個參數是thisValue

調動方法。把this作為thisValueargList作為參數列表。

比如:

function hello(thing) {
    console.log(this + " says hello " + thing);
}

hello.call("Yehuda", "world"); // => Yehuda says hello world

就如所看到的,我們調用了hello方法,this的值是Yehuda而一個多帶帶的參數是"world"。這就是javascript方法調用的本質。你可以把所有其他的方法調用都看做是方便版。

簡單的方法調用

顯然用call調用方法非常的麻煩。Javascript允許我們這樣調用方法:hello("world")。當我們這樣調用的時候實際上是這樣的:

function hello(thing) {
    console.log("Hello " + thing);
}

// this;
hello("world");

// 等于
hello.call(window, "world");

這個行為會在使用strick mode[2]的時候發生改變:

// this:
hello("world");

// 等于
hello.call(undefined, "world");

上面的例子簡單來說就是:一個方法的調用,比如:fn(...args)其實和fn.call(window[ES5-strict: undefined], ...args)。

注意:上面的規則同樣適用于inline的方法調用。(function(){})()(function() {}).call(window [ES5-strict:undefined])

成員方法

下一個常遇到的調用方法的情況是調用一個對象的方法(person.hello())。在這個情況下,調用的順序是:

var person = {
    name: "Brendan Eich",
    hello: function(thing) {
        console.log(this + " says hello " + thing);
    }
};

// this
person.hello("world");

//等于
person.hello.call(person, "world");

注意:其實hello方法是如何綁定到對象上的。記住我們之前是如何把hello方法定義為一個多帶帶的方法的。我們來看看如果方法是動態綁定到對象上的會發生什么:

function hello(thing) {
    console.log(this + " says hello " + thing);
}

person = {name: "Brendan Eich};
person.hello = hello;

person.hello("world"); //等于person.hello.call(person, "hello");

hello("world"); // "[object DOMWindow]world"

注意方法里的this并不是一成不變的。它總是在被調用的時候被賦值。

使用Function.prototype.bind

如果this的值可以保持不變的話,那就方便多了。一個常用的方法就是使用閉包來讓一個方法的this不再改變:

var person = {
    name: "Brenda Eich",
    hello: function(thing) {
        console.log(this.name + " says hello " + thing);
    }
}

var boundHello = function(thing) {return person.hello.call(person, thing);}

boundHello("world");

雖然我們的boundHello的調用的本質還是boundHello.call(window, "world"),我們來看看bind是如何運作的:

var bind = function(func, thisValue) {
    return function() {
        return func.apply(thisValue, aguments);
    }
}

var boundHello = bind(person.hello, person);

boundHello("world");    // "Brendan Eich says hello world"

為了理解上面的例子,你只需要知道兩個事實。一、arguments是一個類似于數組的對象,它代表了全部傳入方法的參數。二、apply方法和call方法本質上是一樣的,只不過類數組的參數代替了逐個列出的參數。

我們的bind方法只是返回了一個新的方法。當它被調用的時候,我們的新方法調用了傳入的方法,設置了this的值。同時其他的參數也傳入進來。

因為這個基本上就是一個非常通用的模型。ES5給所有的Function都引入了一個新的bind。這個bind是這樣工作的:

var boundHello = person.hello.bind(person);
boundHello("world");

這個在你想把一個方法作為回調傳入的時候非常有用:

var person = {
    name: "Alex Russell",
    hello: function() {
        console.log(this.name + " says hello world");
    }
}

$("#some-div").click(person.hello.bind(person));

// 當div被點擊的時候,"Alex Russell says hello world"就會出現

這確實顯得很笨拙,TC39(指定新的ECMAScript標準的組織)還在制定更加優雅的,向后兼容的方法。

關于jQuery

因為jQuery用了非常的多的匿名方法,它內部調用了call方法來設置回調的this值。比如,所有回調都被用call方法設置了當前的元素為this值,而不是用window作為this的值。

這一點非常有用,因為匿名方法作為回調并不是特別有用,但是它會給剛接觸Javascript的人一種this非常奇怪的印象:總之就是經常改變,難以推斷。

如果你能把一個方法的調用順其自然的理解為func.call(thisValue, ...args)的調用方式,那就可以輕而易舉的理解Javascript里this的值了。

原文鏈接:http://yehudakatz.com/2011/08...

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/85128.html

相關文章

  • javascriptthis理解

    摘要:的關鍵字總是讓人捉摸不透,關鍵字代表函數運行時,自動生成的一個內部對象,只能在函數內部使用,因為函數的調用場景不同,的指向也不同。其實只要理解語言的特性就很好理解。個人對中的關鍵字的理解如上,如有不正,望指正,謝謝。 javascript的this關鍵字總是讓人捉摸不透,this關鍵字代表函數運行時,自動生成的一個內部對象,只能在函數內部使用,因為函數的調用場景不同,this的指向也不...

    jimhs 評論0 收藏0
  • 理解 JavaScript this 關鍵字

    摘要:原文許多人被中的關鍵字給困擾住了,我想混亂的根源來自人們理所當然地認為中的應該像中的或中的一樣工作。盡管有點難理解,但它的原理并不神秘。在瀏覽器中,全局對象是對象。運算符創建一個新對象并且設置函數中的指向調用函數的新對象。 原文:Understanding the this keyword in JavaScript 許多人被JavaScript中的this關鍵字給困擾住了,我想混亂的...

    jayzou 評論0 收藏0
  • 理解 JavaScript call()/apply()/bind()

    摘要:理解文章中已經比較全面的分析了在中的指向問題,用一句話來總結就是的指向一定是在執行時決定的,指向被調用函數的對象。與和直接執行原函數不同的是,返回的是一個新函數。這個新函數包裹了原函數,并且綁定了的指向為傳入的。 理解 JavaScript this 文章中已經比較全面的分析了 this 在 JavaScript 中的指向問題,用一句話來總結就是:this 的指向一定是在執行時決定的,...

    duan199226 評論0 收藏0
  • 【譯】javascriptthis關鍵詞理解

    摘要:在中,當使用關鍵字調用函數構造函數時,函數構造函數中也有這個概念,但是它不是惟一的規則,而且常??梢砸脕碜圆煌瑘绦猩舷挛牡牟煌瑢ο?。因此,我們使用調用函數,可以看到這是對象,并且的屬性是正常的。 一直以來,javascript里邊的this都是一個很難理解的東西,之前看的最多的就是阮一峰老師關于this的理解: http://www.ruanyifeng.com/blo... htt...

    tainzhi 評論0 收藏0
  • js基本操作-this理解

    摘要:基本操作理解寫在前面在面向對象的語言中,關鍵字的含義是明確且具體的,即指代當前對象。一般在編譯期確定下來,或稱為編譯期綁定。全局范圍內當在全部范圍內使用,它將會指向全局對象。輸出瀏覽器中運行的腳本,這個全局對象是。 js基本操作-this理解 寫在前面 在面向對象的語言中,this關鍵字的含義是明確且具體的,即指代當前對象。一般在編譯期確定下來,或稱為編譯期綁定。而在 JavaScr...

    Steven 評論0 收藏0

發表評論

0條評論

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