有人可以解释下面代码中发生的事情吗?我希望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()?
答案 0 :(得分:3)
对象文字不评估冒号左侧的标识符的主要原因是你不强制引用所有文字名称(就像在JSON中那样)。
括号表示法强制您引用属性名称,否则,它将被评估为变量。
在第二个示例中调用toString()
的原因是因为bar
必须转换为字符串以用作属性名称。
在第一个示例中,您只是创建一个文字对象(与{"foo" : 'blah'}
完全相同)。所以永远不要使用变量foo
如果要使用变量名创建对象,则不能使用文字对象表示法,必须使用[]
来强制它调用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!!
答案 1 :(得分:2)
对象文字中的键被视为字符串,而不是解释为变量。这样:
var map = {foo : 'blah'};
相当于:
var map = {"foo" : 'blah'};
和此:
var map = {};
map["foo"] = "blah";
但与此完全不同:
var map = {};
map[foo] = "blah";