首頁>Program>source

我尝試整理一下有關javascript的bind()工作原理的想法。

我知道如果這樣做

var f = function (a) { ... }
var g = f.bind(obj);
g(1)

然後用 obj呼叫f 作為 this1 作為 a

我认為g是f的包裝函式。

但是当我這樣做

var f = function (a) { ... }
var g = f.bind(obj);
g.call(1)

然後用 1呼叫f 作為 thisa 未定義。

所以看来g不仅是一个簡單的包裝器,而且是 call 在某種程度上區分了普通函式和繫結函式。

另一件事是我不能多次多次應用某个函式。

var f = function (a) { ... }
var g = f.bind(obj);
var h = g.bind(1);
h();

然後用 obj呼叫f 作為 thisa 未定義。

此行為的原因是什麼?

Edit

此問题中的構造實際上是錯誤的,請參阅已接受的答案,以了解它们的外观(通常我没有註意到 callbind 总是需要將上下文引數作為第一个引數)。

最新回復
  • 5月前
    1 #

    使用 bind將物件繫結到函式後 ,您無法覆盖它.正如您可以在MDN文件中看到的那樣,它清楚地寫在規範中:

    " bind()函式建立一个新函式(繫結函式),该函式具有与被呼叫函式相同的函式主體(ECMAScript 5術語中的內部呼叫屬性)(繫結函式的目標函式) 將此值繫結到bind()的第一个引數, which cannot be overridden. "

    這意味着,即使您這樣做:

    g.call(1);
    

    您將得到 obj 作為 this ,而不是 1 –在符合規格的瀏覽器上。

    您当然可以繫結多个引數,所以:

    var sum = function(a, b, c) { return a + b + c };
    var sumAB = sum.bind(null, 1, 5);
    var sumC = sumAB.bind(null, 2);
    console.log(sumC());
    

    但是上下文物件將始终是第一个 bind指定的物件 ,因為它不能被覆盖.

    為避免混淆,call的第一个引數是上下文物件( this ),那麼您將拥有其餘的引數。

    這意味着:

    var obj = { foo: function(bar) { console.log(bar) } };
    obj.foo('hello');
    // equivalent to:
    var foo = obj.foo;
    foo.call(obj, 'hello');
    

    希望它会有所帮助。

  • 5月前
    2 #

    您永远不会傳遞任何引數-您只会設置上下文. call 的第一个引數作為上下文被接收( this ),則引數2及更高版本將作為被呼叫函式的引數1及更高版本被接收.同時, bind 建立具有新上下文的新函式-呼叫引數時將傳遞引數。

    以下是通過 1的方法 作為功​​能 f 的說法 a 从您的第一个代碼塊開始:

    f( 1 );
    g( 1 );
    g.call( this, 1 );
    g.apply( this, [ 1 ] );
    

  • c#:設置TabPage標頭颜色
  • inheritance:从wPF中的UserControl繼承