1

有人可以解释下面的代码中发生了什么吗?我希望 toString 会同时为 foo 和 bar 调用,或者两者都不调用。文字对象表示法与在创建对象后向对象添加字段有何不同?

function Obj(v) {
    this.v = v;    
};

Obj.prototype.toString= function() {
    window.alert("to string called for " +
                this.v);
    return this.v.toString();
}        

var foo = new Obj('foo');
var bar = new Obj('bar');

// toString is not called here.
var map = {foo : 'blah'};
// toString is called here.
map[bar] = "blah2";

为什么对象文字不使用 toString() 而添加到现有对象确实使用 toString()?

http://jsfiddle.net/pByGJ/2/

4

2 回答 2

3

对象文字不评估冒号左侧的标识符的主要原因是您不必强制引用所有文字名称(就像在 JSON 中所做的那样)。

括号表示法强制您引用属性名称,如果不这样做,它将被评估为变量。

toString()在第二个示例中调用的原因是bar必须将其转换为字符串才能用作属性名称。

在您的第一个示例中,您只是创建了一个文字对象(与 完全相同 {"foo" : 'blah'})。所以从不使用变量foo

如果要使用变量名创建对象,则不能使用文字对象表示法,必须使用[]which 强制它调用toString()

这是一个在一个表达式中创建具有变量名的对象的函数。

function obj(key, value /*, key, value, ... */) {
    var obj = {};
    for (var i = 0, ln = arguments.length ; i < ln; i+=2) {
        obj[arguments[i]] = arguments[i+1];
    }
    return obj;
}

更清晰的例子

您的变量名称和值相同的事实无助于理解问题。让我建议这段代码

var foo = new Obj('fooValue');
var bar = new Obj('barValue');

var map = {foo : 'blah'};
map[bar] = "blah2";

// You expect map to be {fooValue: 'blah', barValue: 'blah2'}
// But it's {foo: 'blah', barValue: 'blah2'}

做你需要的,使用我的obj功能

// Almost as clear as literal notation ???
var map = obj(
    foo, 'blah',
    bar, 'blah2'
);
// map = {fooValue: 'blah', barValue: 'blah2'} Yay!!
于 2012-10-26T18:34:03.690 回答
2

对象文字中的键被视为字符串,而不是解释为变量。这:

var map = {foo : 'blah'};

相当于:

var map = {"foo" : 'blah'};

还有这个:

var map = {};
map["foo"] = "blah";

但与此完全不同:

var map = {};
map[foo] = "blah";
于 2012-10-26T18:45:34.847 回答