Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

第 76 题:输出以下代码运行结果 #125

Open
mengsixing opened this issue May 16, 2019 · 16 comments
Open

第 76 题:输出以下代码运行结果 #125

mengsixing opened this issue May 16, 2019 · 16 comments
Labels

Comments

@mengsixing
Copy link

// example 1
var a={}, b='123', c=123;
a[b]='b';
a[c]='c';
console.log(a[b]);


// example 2
var a={}, b=Symbol('123'), c=Symbol('123');
a[b]='b';
a[c]='c';
console.log(a[b]);


// example 3
var a={}, b={key:'123'}, c={key:'456'};
a[b]='b';
a[c]='c';
console.log(a[b]);

@mengsixing
Copy link
Author

这题考察的是对象的键名的转换。

  • 对象的键名只能是字符串和 Symbol 类型。
  • 其他类型的键名会被转换成字符串类型。
  • 对象转字符串默认会调用 toString 方法。
// example 1
var a={}, b='123', c=123;
a[b]='b';

// c 的键名会被转换成字符串'123',这里会把 b 覆盖掉。
a[c]='c';  

// 输出 c
console.log(a[b]);
// example 2
var a={}, b=Symbol('123'), c=Symbol('123');  

// b 是 Symbol 类型,不需要转换。
a[b]='b';

// c 是 Symbol 类型,不需要转换。任何一个 Symbol 类型的值都是不相等的,所以不会覆盖掉 b。
a[c]='c';

// 输出 b
console.log(a[b]);
// example 3
var a={}, b={key:'123'}, c={key:'456'};  

// b 不是字符串也不是 Symbol 类型,需要转换成字符串。
// 对象类型会调用 toString 方法转换成字符串 [object Object]。
a[b]='b';

// c 不是字符串也不是 Symbol 类型,需要转换成字符串。
// 对象类型会调用 toString 方法转换成字符串 [object Object]。这里会把 b 覆盖掉。
a[c]='c';  

// 输出 c
console.log(a[b]);

@sisi529
Copy link

sisi529 commented May 17, 2019

Got it!

@1998yyh
Copy link

1998yyh commented May 17, 2019

牛皮~ 看起来又是不会的知识

@sherry007
Copy link

我是这样的,看完解析,才恍然觉得我好像以前记过这个啊!!

@fiveLucky
Copy link

我是知道了这个题考察的 对象 键名转换,我知道键名是string,但是第三个我想成了 stringify ,toString就比较容易理解了

@LiuL0703
Copy link

前面说的很清楚了,除了Symbol,如果想要不被覆盖 可以使用ES6提供的Map

var a=new Map(), b='123', c=123;
a.set(b,'b');
a.set(c,'c');
a.get(b);  // 'b'
a.get(c);  // 'c'

@carior
Copy link

carior commented May 24, 2019

喜欢这种 看着简单却做不对的题目TT

@runJaelyn
Copy link

对象类型应该是调用 String() 方法转为字符串吧。

@aeolusheath
Copy link

javascript 普通对象的key都是字符串。

所以:

1,a[c]会先将c转换为字符串,然后再赋值。
2,symbol也可以作为普通对象的key,而且这两个symbol不是相等的。
3,先将对像转换为字符串,然后赋值,所以第二个覆盖了第一个,如果给对象增加一个toString()方法那就会不一样了。

@yygmind
Copy link
Contributor

yygmind commented Dec 16, 2019

// example 1
var a={}, b='123', c=123;  
a[b]='b';
a[c]='c';  
console.log(a[b]);

---------------------
// example 2
var a={}, b=Symbol('123'), c=Symbol('123');  
a[b]='b';
a[c]='c';  
console.log(a[b]);

---------------------
// example 3
var a={}, b={key:'123'}, c={key:'456'};  
a[b]='b';
a[c]='c';  
console.log(a[b]);

@loveyuxuan
Copy link

看完流下了没有技术的泪

@soraly
Copy link

soraly commented Jun 29, 2020

输出以下代码运行结果

// example 1
var a={}, b='123', c=123;  
a[b]='b';
a[c]='c';  
console.log(a[b]);

---------------------
// example 2
var a={}, b=Symbol('123'), c=Symbol('123');  
a[b]='b';
a[c]='c';  
console.log(a[b]);

---------------------
// example 3
var a={}, b={key:'123'}, c={key:'456'};  
a[b]='b';
a[c]='c';  
console.log(a[b]);
  • 第一题,JS里对象的key都是字符串或者symbol,其他类型的都会被转换成字符串,所以b和c都是'123',指向同一个属性,所以会被覆盖,输出 c
  • 第二题,symbol可以作为对象的key且任何一个symbol的值都是唯一的不会被覆盖,所以输出b
  • 第三题,对象当作key时,会调用toString方法转换成字符串,所以两个key都是[object Object],所以输出c

@ysyfff
Copy link

ysyfff commented Jan 29, 2021

再加一题

// example 4
var a={}, b=function(){return 1} c=function(){return 2};
a[b]='b';
a[c]='c';
console.log(a[b]);

@qinyakang
Copy link

再加一题

// example 4
var a={}, b=function(){return 1} c=function(){return 2};
a[b]='b';
a[c]='c';
console.log(a[b]);

你这代码书写有问题,少了逗号啊!function也会调用toString方法,所以结果是b

@Yangfan2016
Copy link

'b' 同名key 被后面的赋值覆盖
'c' Symbol 生成的值是唯一的,即可 key是一样的 ,不相等 (Symbol('123')===Symbol('123') // false)
'b' 对象的key 只可以是 string 或 Symbol 类型,其他类型会转换为 string ,即调用 toString (({key:'123'}).toString()===({key:123}).toString() // true)

@zdd
Copy link

zdd commented Aug 22, 2022

这题考察的是对象的键名的转换。

  • 对象的键名只能是字符串和 Symbol 类型。
  • 其他类型的键名会被转换成字符串类型。
  • 对象转字符串默认会调用 toString 方法。
// example 1
var a={}, b='123', c=123;
a[b]='b';

// c 的键名会被转换成字符串'123',这里会把 b 覆盖掉。
a[c]='c';  

// 输出 c
console.log(a[b]);
// example 2
var a={}, b=Symbol('123'), c=Symbol('123');  

// b 是 Symbol 类型,不需要转换。
a[b]='b';

// c 是 Symbol 类型,不需要转换。任何一个 Symbol 类型的值都是不相等的,所以不会覆盖掉 b。
a[c]='c';

// 输出 b
console.log(a[b]);
// example 3
var a={}, b={key:'123'}, c={key:'456'};  

// b 不是字符串也不是 Symbol 类型,需要转换成字符串。
// 对象类型会调用 toString 方法转换成字符串 [object Object]。
a[b]='b';

// c 不是字符串也不是 Symbol 类型,需要转换成字符串。
// 对象类型会调用 toString 方法转换成字符串 [object Object]。这里会把 b 覆盖掉。
a[c]='c';  

// 输出 c
console.log(a[b]);

讲得很好,补充一下链接:https://tc39.es/ecma262/multipage/abstract-operations.html#sec-topropertykey

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests