Javascript数组/函数对象的引用

时间:2013-03-15 17:26:49

标签: javascript arrays function object pass-by-reference

假设:

function shout(){ alert('Hello!'); }
var dasarray = [ shout ];

shout();
dasarray[0]();

shout = function(){ alert('World!'); }

shout();
dasarray[0]();

输出:

Hello!

Hello!

World!

Hello!

我希望dasarray收到对函数shout的引用,但遗憾的是第4个输出也是hello。如果我假设正确,我能够正确修改shout函数,但这导致我假设该函数未通过引用传递到dasarray

我已经用对象尝试了这个例子,而不是数组:

dasarray = { myfunction: shout }

同样令人失望的结果。

我的目的是拥有/带有函数的数组/对象,这些数组/对象按顺序运行并且可以实时扩展。 例如,使用新功能扩展javascript并向现有事件添加额外的函数调用,这些调用以正确的顺序运行。

那么,有没有想过如何通过引用将函数放入数组/对象?


编辑:谢谢你的好答案。我只想解释一下,我选择了Eli的答案,因为它引导我进入这个设置:

zzz = {
    calls: [],
    shout: function(message) {
        alert('Shouting: ' + message);
    },
    initialize: function () {
        zzz.calls.push(['shout','Hello World']);
        zzz.calls.push(['shout','this is']);
        zzz.calls.push(['shout','my last shout!']);
        zzz.run();

        zzz.shout = function(){ alert('modified!'); };
        zzz.run();
    },
    run: function () {
        $.each(zzz.calls, function(){ zzz[this[0]](this[1]); }); // <- Using jQuery $.each here, just to keep it easy       
    }
};

zzz.initialize();

2 个答案:

答案 0 :(得分:7)

  

我希望dasarray收到对函数shout

的引用

确实如此。它接收对变量 shout的引用。 (函数声明中函数名称定义的符号,对于几乎所有意图和目的而言,都是一个变量 - 这就是为什么以后可以分配给它的原因。)所以后面的行更改变量:

shout = function(){ alert('World!'); }

...对dasarray中对早期函数的引用没有影响。

将对象引用视为一个值,说明在哪里找到一个对象。当你这样做时:

function shout(){ alert('Hello!'); }

...符号shout收到,说明找到该功能的位置,如下所示:

Variable <code>shout</code> pointing to function object

然后当你这样做:

var dasarray = [ shout ];

... value 放在数组的第一个条目中。现在符号shoutdasarray中的第一个条目都具有相同的值,这告诉JavaScript引擎在内存中找到该函数对象的位置。所以我们有这个:

Variable <code>shout</code> and <code>dasarray</code> entry 0 pointing to same function object

但变量shoutdasarray中的条目彼此之间没有任何联系。

然后你这样做:

shout = function(){ alert('World!'); }

...创建一个新函数并在变量shout中存储一个新值,说明新函数的位置。但这对dasarray条目0中存储的值没有影响。我们最终得到了这个:

Var <code>shout</code> pointing to second function, <code>dasarray</code> entry 0 pointing to first function

我之所以说“价值”很多,因为这就是“对象引用”:一个值,就像值5一样。只是使用值的方式是查找对象所在的位置。当您将该值从一个变量分配给另一个变量时,该值将被复制,就像将值5从一个变量复制到另一个变量时复制一样。

我不能说我非常喜欢Eli的解决方法,我宁愿对它更直接,并以简单的方式使用对象:

var obj = {
    shout: function() { alert("Hello!"); }
};
var dasarray = [ obj ];

obj.shout();                               // Hello!
dasarray[0].shout();                       // Hello!

obj.shout = function() { alert("World"); };

obj.shout();                               // World!
dasarray[0].shout();                       // World!

答案 1 :(得分:3)

我同意T.J.的回答。但是,如果您想要进行某种解决方法,可以创建一个始终从函数缓存中“及时”查找的函数。见fiddle

var getFunctionRef = function(funcName)
{
    return function() { global[funcName](); };
}

var global = { };
var arr = [];

global.shout = function() { alert('hello'); }

arr[0] = getFunctionRef('shout');

global.shout = function() { alert('world'); }

arr[0]();

这是一个非常基本的例子。有更广泛的方法来做到这一点。但这应该证明这个概念。