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

資訊專欄INFORMATION COLUMN

理解Javascript方法的調(diào)用和“this”

ad6623 / 3311人閱讀

摘要:過去的幾年,我看過很多人對(duì)方法的調(diào)用滿是迷惑。事實(shí)上,這也是說明的作用。這就是方法調(diào)用的本質(zhì)。簡(jiǎn)單的方法調(diào)用顯然用調(diào)用方法非常的麻煩。注意上面的規(guī)則同樣適用于的方法調(diào)用。成員方法下一個(gè)常遇到的調(diào)用方法的情況是調(diào)用一個(gè)對(duì)象的方法。

過去的幾年,我看過很多人對(duì)javascript方法的調(diào)用滿是迷惑。尤其是對(duì)方法里的this的語(yǔ)義抱怨頗多。

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

核心本質(zhì)

首先,我們方法調(diào)用的本質(zhì)是一個(gè)方法的call方法[1]。它是如下運(yùn)作的。

創(chuàng)建一個(gè)參數(shù)列表(argList),包含了從頭到尾的全部參數(shù)

第一個(gè)參數(shù)是thisValue

調(diào)動(dòng)方法。把this作為thisValue,argList作為參數(shù)列表。

比如:

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

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

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

簡(jiǎn)單的方法調(diào)用

顯然用call調(diào)用方法非常的麻煩。Javascript允許我們這樣調(diào)用方法:hello("world")。當(dāng)我們這樣調(diào)用的時(shí)候?qū)嶋H上是這樣的:

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

// this;
hello("world");

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

這個(gè)行為會(huì)在使用strick mode[2]的時(shí)候發(fā)生改變:

// this:
hello("world");

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

上面的例子簡(jiǎn)單來說就是:一個(gè)方法的調(diào)用,比如:fn(...args)其實(shí)和fn.call(window[ES5-strict: undefined], ...args)。

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

成員方法

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

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

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

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

注意:其實(shí)hello方法是如何綁定到對(duì)象上的。記住我們之前是如何把hello方法定義為一個(gè)多帶帶的方法的。我們來看看如果方法是動(dòng)態(tài)綁定到對(duì)象上的會(huì)發(fā)生什么:

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并不是一成不變的。它總是在被調(diào)用的時(shí)候被賦值。

使用Function.prototype.bind

如果this的值可以保持不變的話,那就方便多了。一個(gè)常用的方法就是使用閉包來讓一個(gè)方法的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的調(diào)用的本質(zhì)還是boundHello.call(window, "world"),我們來看看bind是如何運(yùn)作的:

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"

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

我們的bind方法只是返回了一個(gè)新的方法。當(dāng)它被調(diào)用的時(shí)候,我們的新方法調(diào)用了傳入的方法,設(shè)置了this的值。同時(shí)其他的參數(shù)也傳入進(jìn)來。

因?yàn)檫@個(gè)基本上就是一個(gè)非常通用的模型。ES5給所有的Function都引入了一個(gè)新的bind。這個(gè)bind是這樣工作的:

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

這個(gè)在你想把一個(gè)方法作為回調(diào)傳入的時(shí)候非常有用:

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

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

// 當(dāng)div被點(diǎn)擊的時(shí)候,"Alex Russell says hello world"就會(huì)出現(xiàn)

這確實(shí)顯得很笨拙,TC39(指定新的ECMAScript標(biāo)準(zhǔn)的組織)還在制定更加優(yōu)雅的,向后兼容的方法。

關(guān)于jQuery

因?yàn)閖Query用了非常的多的匿名方法,它內(nèi)部調(diào)用了call方法來設(shè)置回調(diào)的this值。比如,所有回調(diào)都被用call方法設(shè)置了當(dāng)前的元素為this值,而不是用window作為this的值。

這一點(diǎn)非常有用,因?yàn)槟涿椒ㄗ鳛榛卣{(diào)并不是特別有用,但是它會(huì)給剛接觸Javascript的人一種this非常奇怪的印象:總之就是經(jīng)常改變,難以推斷。

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

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

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

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

相關(guān)文章

  • javascriptthis理解

    摘要:的關(guān)鍵字總是讓人捉摸不透,關(guān)鍵字代表函數(shù)運(yùn)行時(shí),自動(dòng)生成的一個(gè)內(nèi)部對(duì)象,只能在函數(shù)內(nèi)部使用,因?yàn)楹瘮?shù)的調(diào)用場(chǎng)景不同,的指向也不同。其實(shí)只要理解語(yǔ)言的特性就很好理解。個(gè)人對(duì)中的關(guān)鍵字的理解如上,如有不正,望指正,謝謝。 javascript的this關(guān)鍵字總是讓人捉摸不透,this關(guān)鍵字代表函數(shù)運(yùn)行時(shí),自動(dòng)生成的一個(gè)內(nèi)部對(duì)象,只能在函數(shù)內(nèi)部使用,因?yàn)楹瘮?shù)的調(diào)用場(chǎng)景不同,this的指向也不...

    jimhs 評(píng)論0 收藏0
  • 理解 JavaScript this 關(guān)鍵字

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

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

    摘要:理解文章中已經(jīng)比較全面的分析了在中的指向問題,用一句話來總結(jié)就是的指向一定是在執(zhí)行時(shí)決定的,指向被調(diào)用函數(shù)的對(duì)象。與和直接執(zhí)行原函數(shù)不同的是,返回的是一個(gè)新函數(shù)。這個(gè)新函數(shù)包裹了原函數(shù),并且綁定了的指向?yàn)閭魅氲摹? 理解 JavaScript this 文章中已經(jīng)比較全面的分析了 this 在 JavaScript 中的指向問題,用一句話來總結(jié)就是:this 的指向一定是在執(zhí)行時(shí)決定的,...

    duan199226 評(píng)論0 收藏0
  • 【譯】javascriptthis關(guān)鍵詞理解

    摘要:在中,當(dāng)使用關(guān)鍵字調(diào)用函數(shù)構(gòu)造函數(shù)時(shí),函數(shù)構(gòu)造函數(shù)中也有這個(gè)概念,但是它不是惟一的規(guī)則,而且常??梢砸脕碜圆煌瑘?zhí)行上下文的不同對(duì)象。因此,我們使用調(diào)用函數(shù),可以看到這是對(duì)象,并且的屬性是正常的。 一直以來,javascript里邊的this都是一個(gè)很難理解的東西,之前看的最多的就是阮一峰老師關(guān)于this的理解: http://www.ruanyifeng.com/blo... htt...

    tainzhi 評(píng)論0 收藏0
  • js基本操作-this理解

    摘要:基本操作理解寫在前面在面向?qū)ο蟮恼Z(yǔ)言中,關(guān)鍵字的含義是明確且具體的,即指代當(dāng)前對(duì)象。一般在編譯期確定下來,或稱為編譯期綁定。全局范圍內(nèi)當(dāng)在全部范圍內(nèi)使用,它將會(huì)指向全局對(duì)象。輸出瀏覽器中運(yùn)行的腳本,這個(gè)全局對(duì)象是。 js基本操作-this理解 寫在前面 在面向?qū)ο蟮恼Z(yǔ)言中,this關(guān)鍵字的含義是明確且具體的,即指代當(dāng)前對(duì)象。一般在編譯期確定下來,或稱為編譯期綁定。而在 JavaScr...

    Steven 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<