2017-03-02 59 views
0

Object.assign的一個常見用例是修改(或展開替換)對象的屬性而不更改對象的引用,所以其他事物參考也會更新。對於JavaScript中的函數,Object.assign()的等效

有沒有辦法與一個函數的內容做到這一點?

因此,舉例來說:

const a =() => console.log('a'); 
const b = a; 
doSomethingMagicalHere(b,() => console.log('b')); 
b(); // prints 'b' 
a(); // prints 'b' 
+2

爲什麼不只是替換持有該函數的對象上的函數呢?使它成爲一個讓,而不是一個const – the8472

+0

等價的是,這兩個函數的引用將是相同的。與C中的指針類似。您可以在不更改引用的情況下更改它的值,因此當您更改引用的內容時,另一個的內容也會更新。這是一種延伸,可能不存在,但我希望有一些我不知道的東西。正確的答案將使我的示例代碼功能如上所述。 – samanime

+0

@ the8472我的例子過於簡單,但在實際的例子中,我試圖模擬/存根一個React組件,它實際上是一個函數,唯一的方法是更新函數的功能,而不僅僅是分配一個新的值(在一個測試文件中),因爲新的值不會反映在實際的代碼中。 – samanime

回答

0

是否有修改/替換功能的內容呢?

不,這是完全不可能的。一個函數的行爲(即調用它的行爲)在Javascript中是不可變的。

當然,如果你事先知道你將要改變功能的行爲,可以使功能依賴於一些外部,可交換狀態的封閉,以確定它應該做的:

const a = function f(...args) { return f.contents.call(this, ...args); } 
a.contents =() => console.log('a'); 
a(); // prints 'a' 
Object.assign(a, {contents(){ console.log('b') }}); 
a(); // prints 'b' 
+0

謝謝,我也曾想過這樣的事情。不幸的是在我的特殊情況下,它是React,它創建了ES6和JSX Harmony語法的函數轉換,所以我不能直接控制函數的發生。 – samanime

+0

@Bergi你的迴應「函數的行爲(即調用它的行爲)在Javascript中是不可變的。」提醒我這個問題:http://stackoverflow.com/questions/41478219/proxying-a-recursive-function – Hrishi

+0

@samanime這不需要做任何與語法(你在ES5中做同樣的事情),你只需要來控制函數定義(或者能夠覆蓋它)。也許你應該[問一個新的問題](http://stackoverflow.com/questions/ask)與你的實際使用案例 – Bergi

-1

首先,有一件事我沒有你樣的理解,使用常量的。如果您在第3行重新分配b,爲什麼要使用const b

無論如何,在Javascript中,大多數變量都使用引用。所以,舉例來說,在下面的代碼中,常量一個定義爲功能和變量b一個一個參考,所以b分配一個新的功能時,你實際上分配

const a =() => console.log('a'); 
var b = a; 
b =() => console.log('b'); 
a(); // prints 'b' 

我希望我沒有錯過你的觀點。

編輯#1

而不是聲明一個函數一個作爲將會在後面被重新分配一個const,我該函數存儲在一個靜態對象。對象引用/指針本身是一個常量,但它的內容,它的屬性不被認爲是不可變的。 (https://medium.com/javascript-scene/javascript-es6-var-let-or-const-ba58b8dcde75#.whv1jizih

// Define a constant reference/pointer to the static object oA 
 
const oA = { 
 
\t // Define mutable property "f" 
 
\t f:() => console.log('a') 
 
}; 
 
// Define an other const ref to the same object called oB 
 
const oB = oA; 
 
// Update the value pointed by the oB.f ref 
 
oB.f =() => console.log('b'); 
 
// Call oB.f // 'b' expected 
 
oB.f(); 
 
// Call oA.f // 'b' expected 
 
oA.f(); 
 
// Using Object.defineProperty 
 
Object.defineProperty(oA, 'f', { 
 
\t __proto__: null 
 
    , value:() => console.log('f') 
 
}); 
 
// Call oB.f // 'f' expected 
 
oB.f(); 
 
// Call oA.f // 'f' expected 
 
oA.f();

+0

我的例子有點偏離。我已經更新了它。 const的要點雖然是我不想改變**引用**,只是它的值(有點像C中的指針)。 – samanime

+0

即使我仍然不明白* whys *,我更新了我的評論。看看編輯#1 – Booster2ooo

+0

分配給b不會影響第一種情況。 Javascript確實使用了引用,正如通過傳遞(引用)數組和對象並對它們進行變異所表明的那樣,但在這種情況下,您可以爲指向新函數的b指定一個新的引用。一個類似的C類似物是a和b都是指針,並且你給b指定了一個新的指針並且期望a也被更新。 –