javascript - vue用法 - vue組件




為什麼Javascript不能正確綁定我的點表達式? (4)

因為當你這樣做(true ? ''.toLowerCase : ''.toUpperCase)()你不是調用綁定到一個字符串的函數。 你只是在沒有任何上下文的情況下調用函數。

考慮下面的例子:

var obj = {
    objname: "objname",
    getName: function() {
        return this.objname;
    }
}

當你用obj.getName()調用它時,它正確地返回值,但是當你做這樣的事情:

var fn = obj.getName
fn() // returns undefined because `fn` is not bound to `obj`

這個問題在這裡已經有了答案:

我想知道是否點抽象方法(如dog.bark )綁定在運行時或在編譯時。 我的問題涉及下面的代碼,它會引發一個錯誤:

(true ? ''.toLowerCase : ''.toUpperCase)()

但是以下不是:

true ? ''.toLowerCase() : ''.toUpperCase()

為什麼我的字符串文字在第一個例子中沒有得到解決?


因為這些方法適用於this上下文,在你的例子中, this不確定的

通過使用bind方法覆蓋變量的一種方法:

(true ? ''.toLowerCase : ''.toUpperCase).bind('Hello')();

這將返回hello


在第一個例子中,首先對括號中的表達式進行求值,這會導致對toLowerCasetoUpperCase的函數引用,然後對未定義的表達式([expression])()的結果調用該函數。 這是非法的。

然而,在第二個例子中,在第三次比較評估期間,在空字符串上調用toLowerCasetoUpperCase ,並將函數的返回值分配給左側操作數。 分配給未定義的不是非法的。

''[(true ? 'toLowerCase' : 'toUpperCase')]()


這實際上很簡單,一旦你得到如何在JavaScript的方法在幕後工作。

toUpperCase是一種方法。 這是一個對特定對象進行操作的函數...通常通過this變量。

Javascript是一個原型語言...意味著附加到對象的功能只是功能,可以復制。 在幕後有一些工作可以確保在你調用一個方法的時候this設置是正確的,但是這個工作只有當你把它作為一個方法調用時才會發生......就像在obj.method()窗體中一樣。

換句話說: ''.toUpperCase()確保在你調用它時設置為字符串''

當你把它稱為toUpperCase() this並沒有被設置為特定的東西(在這種情況下,不同的環境會做不同的事情)

你的代碼可以重寫為:

var function_to_call;
 if (true) {
    function_to_call = ''.toLowerCase;
 } else {
    function_to_call = ''.toUpperCase;
 }

 function_to_call();

因為你的函數調用: function_to_call()不在object.method()語法中,所以把它設置成正確的對象的事情沒有完成,你的函數調用執行時沒有設置你想要的。

正如其他人已經指出的,你可以使用func.call(thing_to_make_this)或者func.apply()來明確地附加正確的東西。

我發現使用.bind() - 這在我看來是極其不足的。 function_name.bind(this_object)為您提供了一個新的函數,它總是將this附加到正確的東西上:

// assuming function_to_call is set
function_that_works = function_to_call.bind(my_object)

function_that_works(); // equivalent to my_object.function_to_call()

這意味著你可以傳遞你從bind()獲得的函數,就像你正常的函數一樣,它將在你想要的對像上工作。 這在回調中特別有用,因為您可以創建一個匿名函數,該函數綁定到在其中創建的對象:

// this won't work because when this runs, 'this' doesn't mean what you think
setTimeout(function() { this.display_message('success'); }, 2000);

// this will work, because we have given setTimeout a pre-bound function.
setTimeout(function() { this.display_message('success'); }.bind(this), 2000); 

TL; DR:你不能把一個方法作為一個函數來調用,並期望它能夠工作,因為它不知道應該是什麼。 如果你想使用這個函數,你必須使用.apply().bind()來確保在函數執行的時候this設置是正確的。

希望有所幫助。





oop