2015-04-04 129 views
1

我想能夠在javascript中合併對象和函數。目前,我有這樣的代碼:Javascript過載圓括號

var Functor = function(f, prop) { 
    var inst = function() {return inst.__op__.apply(this, arguments)} 
    inst.__op__ = f 
    for (var key in prop) 
    inst[key] = prop[key] 
    return inst 
} 

用法是這樣的:

var x = Functor(function(arg) {console.log(arg)}, {qwe:123}) 
console.log(x.qwe) // 123 
x(321) // 321 

但我有兩個問題:首先,我不喜歡複製從prop參數屬性返回inst,我像那裏有某種鏈接到prop。其次,我想能夠在第一個Functor參數地址獲得鏈接到inst。看來我的問題可以通過new關鍵字來改變Functor的功能。但我無法弄清楚如何做到這一點。

重要特徵是,我是能夠改變__op__財產(這是一種()運營商的),我也可以結合的結果,並得到正確的行爲:

var x = Functor() 
x.__op__ = console.log 
var echo = x.bind(console) 
echo(123) // 123 

我將不勝感激,如果有人能夠幫助我有我的任何問題。
下面是使用代碼小提琴複製有:http://jsfiddle.net/avmhbyzr/

+1

我很難理解你真的在這裏問什麼?也許如果你描述了你試圖解決的更高層次的問題,我們會更好地瞭解建議的內容與你現在正在做的不同。你可能還想閱讀[XY問題](http://meta.stackexchange.com/questions/66377/what-is-the-xy-problem),因爲這似乎是你在做什麼(描述一個問題與您嘗試的解決方案,而不是描述你試圖解決的實際問題)。 – jfriend00 2015-04-04 05:48:34

+1

我全都回答X的問題(即使有Y)..但我確實同意更多的上下文會使'問題'/'問題'更加明顯。例如。爲什麼*是*複製的屬性?爲什麼*是* __op__'屬性,而不是直接關閉'f'?爲什麼'apply'中使用的返回閉包的'this'? – user2864740 2015-04-04 05:50:40

+0

@ user2864740還沒有更高級別的問題,我只是想能夠做到這一點。 1)我複製屬性,因爲我不知道如何讓返回值具有這些屬性。這是我的問題之一。 2)我使用'__op__'是因爲我希望能夠更改'()'對我的值做什麼,這在最後一個示例中顯示。 3)我在那裏使用'this',這樣''調用我的值''調用,綁定,應用'綁定到'()'操作符的'this'(例如'console.log',除非綁定到'console')。 – 2015-04-04 06:01:29

回答

1

爲了避免複製了所有屬性從prop,可以設置propinst原型。由於inst是一個函數(不是普通對象),因此您無法控制其構造函數(它必須是Function),因此更改其原型的唯一方法是通過內部的__proto__屬性。

直接的缺點是,您無法訪問函數的所有方法,例如,你不能調用x.call()。但是你可以通過將Function.prototype鏈接到prop來解決它。請參閱下面的代碼。

var Functor = function(f, prop) { 
    var inst = function() { 
     return inst.__op__.apply(this, arguments) 
    } 
    // Setup prototype chain: inst -> prop -> Function.prototype 
    prop.__proto__ = inst.__proto__ 
    inst.__proto__ = prop 

    inst.__op__ = f 
    return inst 
} 

!function() { 
    var x = Functor(null, {qwe:123}) 
    console.log(x.qwe) // 123 

    // Method 1: bind the context to __op__ 
    x.__op__ = console.log.bind(console) 
    x(321) // 321 

    // Method 2: call x with the context 
    x.__op__ = console.log 
    x.call(console, 321) // 321 
}() 

至於使用的this,你已經正確地通過Function.prototype.apply傳遞上下文__op__inst

傳遞上下文的方式是通過調用帶有上下文(方法2)的x或更笨拙的console.x = x; console.x(321)。如果你不想這樣做,你總是可以將上下文綁定到__op__(方法1)。

請記住,當一個函數被執行時,它需要上下文(this)和參數。上下文要麼永久綁定到函數(方法1),要麼就地提供(方法2)。

+0

我有這個想法:'prop .__ proto__ = inst .__ proto__'。問題是,我不想修改'prop'對象,以致它失去了它的一部分屬性。我非常想要的是相反的:完全訪問它的內容。多繼承會有所幫助,但不幸的是沒有一個。至於這個問題,這兩種方法都不是我想要的。這一個'x .__ op__ = console.log.bind(console)'我寧願看到'x .__ op__ = console.log; x = x.bind(console)',這樣'x'就像一個放入'__op__'中的函數一樣工作。 – 2015-04-04 06:19:00

+0

'Functor'的這個定義已經與這段代碼一起工作:'x .__ op__ = console.log; echo = x.bind(console);回聲(321)'。那麼問題是什麼? – 2015-04-04 06:22:29

+0

是的,這有效。但是當'x'沒有綁定任何東西時,我不能''__op__'中的'this'作爲到'x'的鏈接。 – 2015-04-04 06:24:51