如何指定对象的新实例化?

时间:2011-12-06 09:24:16

标签: javascript

请参阅以下简化代码:

myVar= 1;
myFunc = function() {
    return { val : myVar };
};
myInstantiation = new myFunc();
console.log(myInstantiation ); //{val:1}
console.log(myVar); //1
myVar=2;
console.log(myInstantiation );//{val:1}
console.log(myVar); //2

有什么方法可以声明myInstantiationmyFunc以便仍然做同样的事情(例如实例化对象)但是这样可以让我改变myVar并将此更改反映在myInstantiation

例如,我希望输出为

console.log(myInstantiation );//{val:2}
console.log(myVar); //2

2 个答案:

答案 0 :(得分:2)

不是直接的,没有(好吧,你可以使用ECMAScript5)。表达式

return { val: myVar };

...获取myVar并将其分配给新对象的val属性。 val属性的值与myVar的值之间没有持久的联系。

执行所需操作的直接方法是使val成为函数而不是属性:

myVar = 1;
myFunc = function() {
    return {
        val: function() {
            return myVar;
        }
    };
};
myInstantiation = new myFunc();
myVar = 2;
alert(myInstantiation.val()); // alerts "2"

Live example

如果 是一个属性,则可以使用ECMAScript5:您可以定义一个在有人使用新的Object.defineProperty函数访问对象属性时调用的函数:

myVar = 1;
myFunc = function() {
    var rv = {};
    Object.defineProperty(rv, "val", {
        get: function() {
            return myVar;
        },
        set: function(newVal) {
            myVar = newVal;
        }
    });
    return rv;
};
myInstantiation = new myFunc();
myVar = 2;
alert(myInstantiation.val); // alerts "2"

Live example - 在Chrome中运行,最新版本的Firefox,或最近的Safari(但不是Opera或任何版本,到目前为止,IE)。

它仍然是一个函数调用,其开销意味着,但使用myInstantiation的代码将其视为属性访问。 (这很方便,但在某些方面会产生误导。)

Object.defineProperty仅适用于支持新ECMAScript5功能的JavaScript引擎,特别是IE浏览器。如果没有显式的函数调用,就没有标准做你正在做的事情的方式(Mozilla在标准之前做了他们自己的事情,但现在已经弃用了,只能在几个浏览器中使用)。


您的代码存在一些问题我应该指出:

  1. 您没有声明自己的变量,因此您正在成为Horror of Implicit Globals的牺牲品。

  2. 您的myFunc定义为:

    myFunc = function() {
        return { val: myVar };
    };
    

    ...但是你用new来调用它:

    myInstantiation = new myFunc();
    

    由于你的函数返回一个对象,new没有用处,你可以做

    myInstantiation = myFunc();
    

    这是因为new的工作方式:它创建了一个对象,使用myFunc.prototype中的原型初始化该对象,然后调用myFunc并将this设置为新的对象。如果myFunc未返回任何内容或返回基本类型(或null),则new表达式的结果是new创建的新对象。但是如果myFunc返回一个对象(就像你的那样),那么new创建的新对象就会被丢弃,而是使用你的对象。因此new具有与您类似的功能是无关紧要的。

答案 1 :(得分:-1)

在JavaScript中,某些类型按值传递,而其他类型则通过引用传递。特别是,整数和其他基本类型按值传递,因此您无法直接检索指向它们的指针。

但是,如果你使用Integer构造函数(我不记得JavaScript有一个标准的构造函数),它包装了原始整数,你可以传递指向Integer的指针反而是对象。这将允许通过指针更新值。

自从我使用JavaScript以来已经有一段时间了,所以我不确定这个下一个想法是否可行。实例化新函数时,该函数将关闭当前在范围内的变量。这意味着您应该能够做到这样的事情:

myInstantiation = new myFunc(new function(newValue) { myVar = newValue } );

然后您可以在myFunc中使用它。 (语法可能有些偏差,但我认为这个想法应该有效。就像我说的那样,我不再真正做JavaScript了。)

修改

所以,是的,就你的问题而言,最后一部分毫无意义 - 我的情况倒退了。但是,您可以使用双重功能:

myInstantiation = new myFunc(new function() { return myVar } );

通过调用给定的函数而不是直接使用myVar,可以在myFunc内看到更改的内容。如果您希望轻松进行双向通信,则可以使用之前的功能和新的功能来从myVar内获取/设置myFunc