繁体   English   中英

JavaScript 数组/函数对象引用

[英]JavaScript array/object of functions 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 ,但遗憾的是第四输出也打招呼 如果我假设正确,我就能够正确修改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();

我原以为 dasarray 收到了对函数shout的引用

确实如此。 没有收到对变量shout的引用。 (在函数声明中由函数名称定义的符号,几乎所有的意图和目的,都是一个变量——这就是为什么你可以稍后分配给它。)所以你后面的行更改了该变量:

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

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

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

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

...符号shout接收一个,说明该函数的位置,如下所示:

指向函数对象的变量喊叫

然后当你这样做时:

var dasarray = [ shout ];

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

指向同一函数对象的变量喊叫和 dasarray 条目 0

但是变量shoutdasarray的条目dasarray之间没有任何联系。

然后你这样做:

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

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

var 指向第二个函数,dasarray 条目 0 指向第一个函数

我在上面说“值”很多,因为这就是“对象引用”的含义:一个值,就像值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!

我同意TJ 的回答 但是,如果您想采取某种解决方法,您可以创建一个始终从函数缓存中进行“及时”查找的函数。 看到这个小提琴

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]();

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM