Javascript对象如何引用值本身?

Eri*_*ond 158 javascript object

可以说我有以下javascript:

var obj = {
 key1 : "it ",
 key2 : key1 + " works!"
};
alert(obj.key2);
Run Code Online (Sandbox Code Playgroud)

"key1未定义"时出现此错误.我试过了

this.key1
this[key1]
obj.key1
obj[key1]
this["key1"]
obj["key1"]
Run Code Online (Sandbox Code Playgroud)

他们似乎从来没有定义过.

如何让key2引用key1的值?

pen*_*ake 158

也许您可以考虑将属性移除到函数中.我的意思是这样的:

var obj = {
  key1: "it ",
  key2: function() {
    return this.key1 + " works!";
  }
};

alert(obj.key2());
Run Code Online (Sandbox Code Playgroud)

  • 在ES6中,您可以用`get key2(){...}`替换`key2:function(){...}`,然后调用它时不需要使用括号:`alert(obj.key2) ;` (17认同)
  • 它只有在你有一个扁平的`obj`时才有效,就像你的例子中那样.如果您有嵌套键,它将无法工作. (13认同)
  • @OmarSharaki,pencilCake 的函数和你的函数都是匿名的。你的不起作用的原因是你使用的箭头函数看不到“this”。它的内容比我在这里解释的要多得多,但肖恩·维埃拉(Sean Vieira)对[这个问题](/sf/ask/2015883131/)的回答很好地解释了它。 (3认同)
  • @Green True,但您始终可以在创建对象后立即将其分配给绑定函数。`var obj = { ... }; obj.nested.func = function() { ... }.bind(obj);` (2认同)
  • 知道为什么如果使用匿名函数则返回 undefined 吗?`key2: ()=>this.key1+" 有效!"` (2认同)

use*_*291 52

这可以通过使用构造函数而不是文字来实现

var o = new function() {
  this.foo = "it";
  this.bar = this.foo + " works"
}

alert(o.bar)
Run Code Online (Sandbox Code Playgroud)


Tgr*_*Tgr 40

在初始化该对象之前,不能引用对象的属性; 使用外部变量.

var key1 = "it";
var obj = {
  key1 : key1,
  key2 : key1 + " works!"
};
Run Code Online (Sandbox Code Playgroud)

此外,这不是"JSON对象"; 它是一个Javascript对象.JSON是一种用字符串表示对象的方法(恰好是有效的Javascript代码).


Edw*_*rzo 24

一种替代方案是使用getter/setter方法.

例如,如果您只关心读取计算值:

var book  = {}

Object.defineProperties(book,{
    key1: { value: "it", enumerable: true },
    key2: {
        enumerable: true,
        get: function(){
            return this.key1 + " works!";
        }
    }
});

console.log(book.key2); //prints "it works!"
Run Code Online (Sandbox Code Playgroud)

但是,上面的代码不允许您为key2定义另一个值.

因此,如果您想重新定义key2的值,事情会变得有点复杂.它始终是一个计算值.最有可能的是你想要的.

但是,如果您希望能够重新定义key2的值,那么您将需要一个位置来独立于计算来缓存其值.

有点像这样:

var book  = { _key2: " works!" }

Object.defineProperties(book,{
    key1: { value: "it", enumerable: true},
    _key2: { enumerable: false},
    key2: {
        enumerable: true,
        get: function(){
            return this.key1 + this._key2;
        },
        set: function(newValue){
            this._key2 = newValue;
        }
    }
});

console.log(book.key2); //it works!

book.key2 = " doesn't work!";
console.log(book.key2); //it doesn't work!

for(var key in book){
    //prints both key1 and key2, but not _key2
    console.log(key + ":" + book[key]); 
}
Run Code Online (Sandbox Code Playgroud)

另一个有趣的替代方法是使用自初始化对象:

var obj = ({
  x: "it",
  init: function(){
    this.y = this.x + " works!";
    return this;
  }
}).init();

console.log(obj.y); //it works!
Run Code Online (Sandbox Code Playgroud)

  • 我喜欢自初始化对象的方式。谢谢 (2认同)

Del*_*ani 22

因为语句定义obj尚未完成,key1尚不存在.考虑这个解决方案

var obj = { key1: "it" };
obj.key2 = obj.key1 + ' ' + 'works!';
// obj.key2 is now 'it works!'
Run Code Online (Sandbox Code Playgroud)


T.J*_*der 16

那不是JSON对象,它是通过对象文字符号创建的Javascript对象.(JSON是数据交换的文本符号(更多).如果你正在处理JavaScript源代码,而不是处理字符串,那么你就不会处理JSON.)

在对象初始化器中没有办法引用正在初始化的对象的另一个键,因为在初始化器完成之前无法获得对正在创建的对象的引用.(this对于这种情况,没有类似于或类似的关键字.)


Jas*_*son 11

obj一旦进入函数内部,您也可以引用它而不是this.

var obj = {
    key1: "it",
    key2: function(){return obj.key1 + " works!"}
};
alert(obj.key2());
Run Code Online (Sandbox Code Playgroud)

  • 我认为这个答案优于“最佳答案”。obj.key1 始终是“it”,而 this.key1 可以是其他值,具体取决于调用 obj.key2 函数的位置。例如 setTimeout( obj.key2, 100 ); this 指的是窗口对象。 (2认同)

Tho*_*mas 5

这不是JSON.JSON设计简单; 允许任意表达式并不简单.

在完整的JavaScript中,我认为你不能直接这样做.thisobj完全构造被调用的对象之前,您无法引用.所以你需要一个解决方法,那个拥有比我更多的JavaScript-fu的人.