var a = new Object;
var b = new Object;
var c = new Object;
c[a] = a;
c[b] = b;
console.log(c[a] === a);
Run Code Online (Sandbox Code Playgroud)
我测试了上面的代码然后得到了false.如果我尝试console.log(c[a] === b),然后true打印.
为什么?
roy*_*wie 33
这里的问题与如何Object设置密钥有关.来自MDN:
参数
nameValuePair1,nameValuePair2,... nameValuePairN
- 成对的名称(字符串)和值(任何值),其中名称通过冒号与值分隔.
值
- 任何价值.
可以通过三种方式访问对象的值(通过适当的密钥):
var o = {};
var key = "fun";
// method 1:
o[key] = "the key will be equal to `key.toString()"
// method 2:
o.key = "the key will be equal to 'key'"
// method 3:
o["key2"] = "the key will be equal to `key2`"
/*
{
"fun" : "the key will be...", // method 1
"key" : "the key will be...", // method 2
"key2": "the key will be..." // method 3
}
*/
Run Code Online (Sandbox Code Playgroud)
使用括号表示法时,需要注意括号之间的间隙!对象使用该toString方法设置其键和值,除非它们传递一个字符串(然后没有任何意义toString).使用点表示法时,它们.key用作键.
让我们来看看你的情况:
var a = {}
, b = {}
, c = {}
;
c[a] = a;
// `a` is not a string, and we're using brackets, so the key
// will be equal to `key.toString()`:
// a.toString() === "[object Object]"
// Try the following in your console: `{}.toString()`
// Note how this is different from console.log({}), since
// the console exposes your object (that's why the dev console is useful)
// c is now: `{ "[object Object]" : a }`
c[b] = b;
// b is also an object, so `b.toString()` is the same as `a.toString()`
// that means c is now `{ "[object Object]" : b }`
assert c[a] === a
// a.toString() == b.toString() == "[object Object]"
// and we just noted that c was `{ "[object Object]" : b }`
// so of course this is false
assert c[b] === b
// true because c[b] == b;
assert c["[object Object]"] === b;
// also true
assert c.b === b
// false, since `c` has no "b" key (c.b is `undefined`)
Run Code Online (Sandbox Code Playgroud)
对象不是JavaScript对象的有效键,只有字符串
所以,当你这样做时:
c[a] = a;
c[b] = b;
Run Code Online (Sandbox Code Playgroud)
编译器不能像c [a]或c [b]那样使用a或b作为c的键.
但是,它不会失败,因为JavaScript可以解决此问题.首先它弄明白了
因此,JavaScript编译器将调用每个变量的toString().默认情况下,Object.prototype.toString它将返回"[object Object]"-string,因为实现是执行该操作的默认实现,并且该值成为新键
c["[object Object]"] = a;
c["[object Object]"] = b; // overrides the previous
Run Code Online (Sandbox Code Playgroud)
这不是你想要的.问题是toString默认返回总是相同的值,因此assigments将始终转到相同的键.
为了证明toString实际上是问题,你实际上可以做一个可怕的欺骗,让每个对象返回唯一的字符串
// don't do this!!!
(function() {
var id=1;
Object.prototype.toString = function() {
if(!this._id) this._id = id++;
return "Object"+this._id;
}
}());
Run Code Online (Sandbox Code Playgroud)
在c [a]的那个键之后是c ["Object1"]而c [b]将是c ["Object2"],依此类推......并且c [a] == a和c [b] = = b正如预期的那样工作,但在现实生活中这不是一个好的解决方案.
解决这个问题的一种可接受的方法是使用一些其他键,可能是分配给对象的ID,如c [a.id] = a或使用ES6 Map Object,其中任何值(包括Objects)都可以用作键.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map
Map对象是一个简单的键/值映射.任何值(对象和原始值)都可以用作键或值.
| 归档时间: |
|
| 查看次数: |
2320 次 |
| 最近记录: |