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

資訊專欄INFORMATION COLUMN

搞懂JavaScript的Function.prototype.bind[譯]

Pandaaa / 3089人閱讀

摘要:搞懂的譯可能是初學(xué)的人最不關(guān)心的函數(shù),當(dāng)你意識(shí)到需要保持在其他函數(shù)中的上下文,實(shí)際上你需要的是。這就是問(wèn)題所在。整合事件綁定和一個(gè)重大提高就是,和等等。然而,并沒(méi)有原生添加事件到多個(gè)節(jié)點(diǎn)的方式。能力有限,如有疑問(wèn),紕漏,速指出,感謝你

搞懂JavaScript的Function.prototype.bind[譯]

Ben Howdle

binding可能是初學(xué)Javascript的人最不關(guān)心的函數(shù),當(dāng)你意識(shí)到需要『保持this在其他函數(shù)中的上下文』,實(shí)際上你需要的是Function.prototype.bind()。

你第一次碰到問(wèn)題的時(shí)候,你可能傾向于把this賦值給一個(gè)變量,你就可以在上下文改變的時(shí)候,也可以使用。許多人選擇self,_this或者context來(lái)命名。這些都不會(huì)被用到,這樣做也沒(méi)什么問(wèn)題,但是這里有更好的辦法,專門解決這個(gè)問(wèn)題。

我愿意為作用域做任何事,但我不會(huì)that = this

— Jake Archibald (@jaffathecake) February 20, 2013

我們真正在尋求解決的問(wèn)題是什么?

看看這段代碼,把上下文賦值給一個(gè)變量:

var myObj = {

    specialFunction: function () {

    },

    anotherSpecialFunction: function () {

    },

    getAsyncData: function (cb) {
        cb();
    },

    render: function () {
        var that = this;
        this.getAsyncData(function () {
            that.specialFunction();
            that.anotherSpecialFunction();
        });
    }
};

myObj.render();

如果上面直接用this.specialFunction(),結(jié)果是一個(gè)錯(cuò)誤信息:

Uncaught TypeError: Object [object global] has no method "specialFunction"

當(dāng)回調(diào)的時(shí)候,我們需要保持myObj的上下文引用。使用that.specialFunction(),讓我們用that的上下文且正確執(zhí)行函數(shù)。然而,用Function.prototype.bind()可以簡(jiǎn)化一些。

重寫例子:

render: function () {

    this.getAsyncData(function () {

        this.specialFunction();

        this.anotherSpecialFunction();

    }.bind(this));

}
我們剛做了什么?

.bind()就是創(chuàng)建了一個(gè)新函數(shù),當(dāng)我們呼叫時(shí),把他的this賦值。所以我們可以傳遞我們的上下文,this(指向myObj),傳遞進(jìn).bind()函數(shù)。當(dāng)回調(diào)執(zhí)行的時(shí)候,this指向myObj。

如果我們對(duì)Function.prototype.bind()的內(nèi)部實(shí)現(xiàn)有興致,請(qǐng)看下面的例子:

Function.prototype.bind = function (scope) {
    var fn = this;
    return function () {
        return fn.apply(scope);
    };
}

一個(gè)簡(jiǎn)單的例子:

var foo = {
    x: 3
}

var bar = function(){
    console.log(this.x);
}

bar(); // undefined

var boundFunc = bar.bind(foo);

boundFunc(); // 3
瀏覽器兼容性
Browser Version support
Chrome 7
Firefox (Gecko) 4.0 (2)
IE 9
Opera 11.60
Safari 5.1.4

如你所見(jiàn),不幸的是,不支持ie8以下(啥也不說(shuō)了)。
幸運(yùn)的是,MDN為那些原生不支持.bind()的瀏覽器提供了解決:

if (!Function.prototype.bind) {
  Function.prototype.bind = function (oThis) {
    if (typeof this !== "function") {
      // closest thing possible to the ECMAScript 5 internal IsCallable function
      throw new TypeError("Function.prototype.bind - what is trying to be bound is not callable");
    }

    var aArgs = Array.prototype.slice.call(arguments, 1),
        fToBind = this,
        fNOP = function () {},
        fBound = function () {
          return fToBind.apply(this instanceof fNOP && oThis
                                 ? this
                                 : oThis,
                               aArgs.concat(Array.prototype.slice.call(arguments)));
        };

    fNOP.prototype = this.prototype;
    fBound.prototype = new fNOP();

    return fBound;
  };
}
使用方式

學(xué)習(xí)東西時(shí)候,我發(fā)現(xiàn)有效的方式不是認(rèn)真的去學(xué)習(xí)概念,而是去看怎么使用到現(xiàn)在的工作中。如果順利的話,下面某些例子可以被用到你的代碼中解決你面對(duì)的問(wèn)題。

點(diǎn)擊事件處理

其中一個(gè)用處是追蹤點(diǎn)擊(點(diǎn)擊后執(zhí)行一個(gè)動(dòng)作),需要我們?cè)谝粋€(gè)對(duì)象中儲(chǔ)存信息:

var logger = {
    x: 0,
    updateCount: function(){
        this.x++;
        console.log(this.x);
    }
}

我們寫click事件處理,然后呼叫l(wèi)ogger中的updateCount():

document.querySelector("button").addEventListener("click",logger.updateCount);

但我們?cè)炝艘粋€(gè)不必要的匿名函數(shù),保持this的正確指向。
簡(jiǎn)化一下:

document.querySelector("button").addEventListener("click", logger.updateCount.bind(logger));

剛才我們用了.bind()創(chuàng)造一個(gè)新函數(shù)然后把作用域綁定到logger對(duì)象上。

時(shí)間間隔函數(shù)

如果你以前用過(guò)模板引擎(handlebars)或者M(jìn)V*框架,那你應(yīng)該意識(shí)到一個(gè)問(wèn)題的發(fā)生,當(dāng)你呼叫渲染模板,立刻想進(jìn)入新的DOM節(jié)點(diǎn)。
假設(shè)我們嘗試實(shí)例一個(gè)jQuery插件:

var myView = {

    template: "/* a template string containing our