2017-03-02 54 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也被更新。 –