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

資訊專欄INFORMATION COLUMN

關(guān)于JS函數(shù)的bind

CloudwiseAPM / 2143人閱讀

摘要:昨天被人問到的的作用是什么這個倒還能回答出來,之后返回一個新的函數(shù),這個函數(shù)可以保持傳遞的上下文。沒有完全實現(xiàn)規(guī)定的。比如規(guī)定了的和行為。

https://friskfly.github.io/2016/03/24/about-function-bind-in-js/

昨天被人問到j(luò)s的bind的作用是什么?

這個倒還能回答出來,bind 之后返回一個新的函數(shù),這個函數(shù)可以保持傳遞的this上下文。

接著又問了,那么bind兩次不同的上下文會怎樣?

這個一下子就蒙了,因為平時也沒這么用過,于是開始查一下資料。

首先在瀏覽器中測試一下。

function test(){
  console.log(this.a)
}
var bind1 = test.bind({a:1}) //第一次 bind
var bind2 = bind1.bind({a:2}) // 第二次 bind
bind1()
bind2()

結(jié)果如下

1
1

可以看到第二次bind并沒有能再改變this的值。

查一下MDN,F(xiàn)unction.prototype.bind() , 并沒有解釋bind兩次會怎樣。 但是他提供了一個Polyfill,可以了解下bind的實現(xiàn)。

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
                 ? this
                 : oThis,
                 aArgs.concat(Array.prototype.slice.call(arguments)));
        };

    if (this.prototype) {
      // Function.prototype doesn"t have a prototype property
      fNOP.prototype = this.prototype;
    }
    fBound.prototype = new fNOP();

    return fBound;
  };
}

可以看到MDN提供的polyfill的實現(xiàn)是oThis做為參數(shù)傳進來,返回一個新的函數(shù),這個時候函數(shù)是個閉包,仍然可以訪問oThis變量,然后調(diào)用call/apply來實現(xiàn)指定的上下文。 這種情況下,如果bind兩次,相當(dāng)于閉包套閉包,不管套幾層,值都是第一次保存的this值。 即上面polyfill的 oThis 變量。

光看polyfill是不夠了,因為并不知道polyfill實現(xiàn)是不是標準。所以還是要看下規(guī)范。這里我們參考下 ES2015文檔

可以直接看到 19.2.3.2 節(jié) NOTE 2,If Target is an arrow function or a bound function then the thisArg passed to this method will not be used by subsequent calls to F. 如果調(diào)用bind的是一個箭頭函數(shù)或者是已經(jīng)bind過的函數(shù)(bound function),那么再次bind是不會起作用的。 可以看到規(guī)范已經(jīng)定義了這樣的行為產(chǎn)生的結(jié)果,我們可以直接記住這個結(jié)論。

但是這里值得注意的是,我們看到規(guī)范定義的bind操作 和 MDN 上提供的polyfill并不一致。polyfill沒有完全實現(xiàn)ES2015規(guī)定的bind。

比如ES2015 規(guī)定了 bound function 的length 和 name 行為。

Let targetHasLength be HasOwnProperty(Target, "length").
ReturnIfAbrupt(targetHasLength).
If targetHasLength is true, then
  Let targetLen be Get(Target, "length").
  ReturnIfAbrupt(targetLen).
  If Type(targetLen) is not Number, let L be 0.
  Else,
    Let targetLen be ToInteger(targetLen).
      Let L be the larger of 0 and the result of targetLen minus the number of elements of args.
Else let L be 0.

這里會規(guī)定bound function 的 length 屬性,應(yīng)該和bind之前的length一致。

再看name 的行為

Let targetName be Get(Target, "name").
ReturnIfAbrupt(targetName).
If Type(targetName) is not String, let targetName be the empty string.
Perform SetFunctionName(F, targetName, "bound").

這里規(guī)定bound function 的name 應(yīng)該走 SetFunctionName 方法,而這里SetFunctionName之后的返回值應(yīng)該是 bound字符串 + 空格 + 原先函數(shù)的name

......忽略了一些描述
prefix即bound 字符串
If prefix was passed, then
  Let name be the concatenation of prefix, code unit 0x0020 (SPACE), and name.

function a(){}
var b = a.bind()
console.log(b.name)

結(jié)果應(yīng)該是

bound a

而 MDN 的 polyfill 是沒有實現(xiàn)這些細節(jié)的,所以用bind的時候如果依賴于這些,是要注意的。

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

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

相關(guān)文章

  • JS 關(guān)于 bind ,call,apply 和arguments p8

    摘要:同樣會綁定,也會穿參數(shù),但是不會立即執(zhí)行我是內(nèi)部的我是內(nèi)部的類似數(shù)組,但不是真的數(shù)組,好吧,就把它當(dāng)成數(shù)組吧,它同樣擁有而且也可以通過下標訪問關(guān)于下面的官方語言警告在嚴格模式下,第版禁止使用。關(guān)于這3個貨,網(wǎng)上有很多文章介紹,我這邊還是記錄下并加上自己的理解,還有arguments函數(shù)內(nèi)置對象順便也記錄下: 簡單的說apply和call 會綁定第一個參數(shù)的作用域給調(diào)用函數(shù)對象實例,并會執(zhí)行...

    番茄西紅柿 評論0 收藏0
  • Javascript:call(),apply()和bind()

    摘要:在面向?qū)ο蟮闹?,我們了解到在中,一切都是對象。到目前為止,我們已將函?shù)視為由名稱可選,也可以是匿名函數(shù)組成的對象及其在調(diào)用時執(zhí)行的代碼。這意味著,我們可以調(diào)用任何函數(shù),并在調(diào)用函數(shù)中明確指定。和用于完全相同的目的。 What s this 在面向?qū)ο蟮腏S中,我們了解到在JS中,一切都是對象。因為一切都是對象,我們開始明白我們可以為函數(shù)設(shè)置和訪問其他屬性。而this提供了一種更優(yōu)雅的方...

    WrBug 評論0 收藏0
  • Javascript:call(),apply()和bind()

    摘要:在面向?qū)ο蟮闹?,我們了解到在中,一切都是對象。到目前為止,我們已將函?shù)視為由名稱可選,也可以是匿名函數(shù)組成的對象及其在調(diào)用時執(zhí)行的代碼。這意味著,我們可以調(diào)用任何函數(shù),并在調(diào)用函數(shù)中明確指定。和用于完全相同的目的。 What s this 在面向?qū)ο蟮腏S中,我們了解到在JS中,一切都是對象。因為一切都是對象,我們開始明白我們可以為函數(shù)設(shè)置和訪問其他屬性。而this提供了一種更優(yōu)雅的方...

    Sike 評論0 收藏0
  • Javascript:call(),apply()和bind()

    摘要:在面向?qū)ο蟮闹校覀兞私獾皆谥?,一切都是對象。到目前為止,我們已將函?shù)視為由名稱可選,也可以是匿名函數(shù)組成的對象及其在調(diào)用時執(zhí)行的代碼。這意味著,我們可以調(diào)用任何函數(shù),并在調(diào)用函數(shù)中明確指定。和用于完全相同的目的。 What s this 在面向?qū)ο蟮腏S中,我們了解到在JS中,一切都是對象。因為一切都是對象,我們開始明白我們可以為函數(shù)設(shè)置和訪問其他屬性。而this提供了一種更優(yōu)雅的方...

    sarva 評論0 收藏0
  • 你不知道js技巧

    摘要:所謂的高級,其實就是講了一些我們平常用不到或許用了不知道,但是非常實在的東西。比如如果你想檢測里面的屬性值的話,基本上是不可能的。要知道,我們是有情懷的淫。 JS進階 說起這個應(yīng)該算是老生常談了吧。所謂的高級,其實就是講了一些我們平常用不到(或許用了不知道),但是非常實在的東西。算是熟練掌握js的一個必經(jīng)road吧。 檢測函數(shù)類型 其實檢測函數(shù)的類型應(yīng)該算是js的一個痛點,因為js是一...

    edagarli 評論0 收藏0

發(fā)表評論

0條評論

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