2013-03-18 68 views
2

有很多問題和答案涵蓋了這種技術,但我似乎無法找到所需的this上下文爲call()或apply()設置。如何在Array.prototype.slice.call(參數)中設置'this'上下文

我明白

Array.prototype.slice.call(arguments)

是有點相當於

arguments.slice()

arguments被轉換成一個適當的數組對象,但如果我嘗試使用這個約定,我自己對象不起作用。我試着寫一個小的測試這樣做:

var Logger = function(){}; 
Logger.prototype.print = function(msg){ 
    console.log ((new Date()).getTime().toString() + msg); 
}; 

(function(){ 
    var o = { 
    name: "Hi Bob!", 
    }; 

    var l = new Logger(); 
    l.print(o.name); //works fine 
    Logger.prototype.print.call(o.name); //calls print method, but 'msg' is undefined 
}()); 

是否有可以Array.prototypearguments對象,允許該功能的應用程序沒有必要的情況下工作,有些特別的問候?

+0

不,只有你的代碼「有點相當於」'o.name.print()' - 這顯然不是你想要的。有關它的工作方式,請參閱http://stackoverflow.com/q/6763555/1048572。 – Bergi 2013-03-18 16:07:57

回答

1

Logger.prototype.print打印任何地方都不會使用this變量,所以使用call()是毫無意義的。您的函數期望通過msg作爲參數。這就是爲什麼l.print(o.name);有效。

正如你在你的問題說:

Array.prototype.slice.call(arguments) 

類似於arguments.slice()。因此:

Logger.prototype.print.call(o.name); 

o.name.print()類似。正如你所看到的,這是沒有道理的。

如果你真的使用.call(),你可以這樣類似:

Logger.prototype.print.call(null, o.name); 

但是,正如你所看到的,這是愚蠢的,而且更難不僅僅是l.print(o.name);閱讀。

+0

根據你的回答進行一些進一步的測試,現在我明白了。 [http://jsbin.com/iwaric/1/edit](http://jsbin.com/iwaric/1/edit)。所以'arguments'參數實際上成爲'slice()'的上下文,當不帶參數調用時它會返回原始數組的副本。 – mastaBlasta 2013-03-18 16:04:32

+0

@mastaBlasta:是的,這有效。正如你所看到的,所有'。call()'does允許你在函數內部改變'this'(如果使用的話)。在你的情況下,我建議只需堅持'l.print(o.name);'。 – 2013-03-18 16:07:41

+1

我其實並沒有這方面的用途。我剛剛讀過一些使用'Array.prototype.slice.call(arguments)'的其他代碼,然後繼續探索call()如何處理看起來像「數組」的參數。回想起來,答案很明顯 - 背景只是一個對象! – mastaBlasta 2013-03-18 16:10:13

2

slice和你的函數之間的區別是slice使用上下文(this),而你的函數只使用它的參數。

如果你真的想用call您的功能,用它作爲

Logger.prototype.print.call(null, o.name); 

但是,你還不如用

Logger.prototype.print(o.name); 
相關問題