《深入理解ES6》中的代码片段,你能猜对几个?

花了3个周末看完了《深入理解ES6》,其中有许多代码段以及文字描述和我“常识”有些出入,因此记录了下来并加以验证。

有些代码段还是蛮有趣的,再此分享下。正在阅读屏幕的你,能“猜”对几个代码片段呢?

每个代码片段均有编号,格式为为try-xxx-yyy或note-xxx-yyy,其中xxx代表书中的页码,yyy是笔者随意加的名称

 

笔者已经将所有代码片段上传到GitHub中,有兴趣的小伙伴可以戳这里→ pea3nut/read-unes6-demo

代码片段

try-82-keys

最后一个console.log语句要格外注意,笔者错的很离谱

[code lang=text]
var obj ={
a:1,
b:2,
};
Object.setPrototypeOf(obj,{
c:3,
});

console.log(Object.keys(obj));
console.log(JSON.stringify(obj));

var keys1 =[];
for(let key in obj)keys1.push(key);
console.log(keys1);

var keys2 =[];
for(let key in Object.assign({},obj))keys2.push(key);
console.log(keys2);
[/code]

try-87-super

代码略长,主要思想是:this是“墙头草”可以随意被改变,那么super呢?是不是和this一样是“墙头草”呢?

答案是:███████████████请用小刀刮开

[code lang=js]
class A{
say(){
console.log('It\'s A#say.');
};
};
class B extends A{
say(){
console.log('It\'s B#say.');
};
run(){
this.say();
super.say();
};
};

var b =new B;
b.run.call({
say(){
console.log('call');
}
});

console.log('===');

var obj ={
say(){
console.log('It\'s obj.say.');
},
run(){
this.say();
super.say();
}
};

Object.setPrototypeOf(obj,{
say(){
console.log('It\'s proto.say.');
},
});

obj.run();
[/code]

try-99-destructuring

这是书上的一个错误,笔者已经提交了勘误

[code lang=js]
var {a=1,b=2} ={b:undefined};
console.log(a,b);

var [c=3,d=4] =[,undefined];
console.log(c,d);
[/code]

try-112-symbol-tox

代码虽少,但是却非常非常非常难,能答对的应该是很厉害了。。。

友情提示:console.log不一定是会输出什么,throw个错误也说不定哦~~

[code lang=js]
var smb =Symbol('hello');

console.log(smb);
console.log(''+smb);
console.log(1+smb);
console.log(String(smb));
[/code]

try-154-generator-symbol

为了能验证出有效结果,这个片段写的很露骨,大家就当是在看“你知道吗?披萨其实一直是从里往外吃的!”这样的冷知识看看就好

[code lang=js]
var gen =function*(){
yield 1;
yield 2;
};

console.log(gen()[Symbol.iterator] ===gen());
console.log(gen()[Symbol.iterator]()[Symbol.iterator] ===gen()[Symbol.iterator]);

console.log('===');
console.log(...gen());
console.log(...gen()[Symbol.iterator]());
console.log(...gen()[Symbol.iterator]()[Symbol.iterator]());

console.log(Object.getOwnPropertyNames(gen().__proto__.__proto__));
[/code]

try-185-class-name

这算是一个很实用并且大家都在用的知识了,只是很多人可能并没有意识到。。。

这题必须答出为什么才算对哦~~

[code lang=js]
class A{
say(){
console.log(A);
};
};

var B =A;
A =null;

var a =new B();
a.say();
[/code]

try-187-class-name-2

这个代码在不同环境表现不一致,笔者也不知道为什么,若有了解ES6规范的dalao请科普下

[code lang=js]
var A =class{};
var B =function(){};

console.log(A.name);
console.log(B.name);
[/code]

try-198-class-extent-super.js

extends却不调用super,会报错吗?不会报错吗?将代码复制进WebStorm中有惊喜~~

这个片段也需要说出为什么才算答对

[code lang=js]
class A{};
class B extends A{
constructor(){
return {};
};
};

console.log(new B);
[/code]

try-310-class-prototype

本文的初衷只是分享笔记和知识,而不是卖关子哗众取宠,因此下面的片段在注释中已经该出了部分答案

[code lang=js]
class A{};
A.prototype ={b:2};//严格模式会报错
A.prototype.c =3;

var a =new A();

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

try-332-number-safe

这个片段引申出了一个很有趣的问题,那就是

num === num+1
请问在什么条件下上面的表达式会返回true?

答案是2个:

  • IEEE 754存储的整数开始重用二进制时
  • 大浮点数

[code lang=js]
var num1 =Math.pow(2,53);
var num2 =Math.pow(2,53)+1;

console.log(num1);
console.log(num2);

console.log(num1 ===num2);
console.log(Math.pow(2,53) ===Math.pow(2,53)+1);
console.log(num1+1 ===num1);

console.log('===');

console.log(Number.MAX_SAFE_INTEGER);
console.log(Number.isSafeInteger(num1));
console.log(Number.isSafeInteger(num1-1));
console.log(Number.isSafeInteger(Math.pow(2,53)));
[/code]

tyr-120-toPrimitive

此片段可以完美解释try-112-symbol-tox片段

[code lang=js]
var obj =Object.create(null);
obj[Symbol.toPrimitive] =function(hint){
console.log(hint);
return '';
};

console.log(String(obj));
console.log(obj+'');
console.log(+obj);
[/code]

note-216-array-from

这是个相当不错的面试题,大概

(希望我一朝一日可以拿去面试别人)

[code lang=js]
var arrayLike ={
0:'a',
1:'b',
length:2,
*[Symbol.iterator](){
yield this[1];
yield this[0];
},
};

console.log(Array.from(arrayLike));
[/code]

note-259-promise-all

和上面的片段有异曲同工之妙

[code lang=js]
try{
let arrayLike ={
0:Promise.resolve('233'),
length:1,
};
Promise.all(arrayLike);
}catch(e){
console.log('error');
};

var promises =[
new Promise(function(resolve){
setTimeout(function(){
resolve(1)
},90);
}),
new Promise(function(resolve){
setTimeout(function(){
resolve(2)
},10);
}),
new Promise(function(resolve){
setTimeout(function(){
resolve(3)
},50);
}),
];

Promise.all(promises).then(console.log)
[/code]

对ES5非常非常非常熟悉的同学应该了解下面的片段 —— Object.create(null)是个相当风骚的用法

[code lang=js]
var obj =Object.create(null);

console.log(obj+'');
console.log(String(obj));
console.log(Number(obj));
console.log(obj.__proto__ ===Object.prototype);
[/code]

结束

代码片段就差不多到这里,在GitHub的源代码中,还有一些笔者认为“没有必要放上来”的片段,若你有些在意,或者想拿下来跑一跑,欢迎来Star:pea3nut/read-unes6-demo

若你对于文章内容或代码有异议,可在上方的GitHub链接中发送issue

发表新的回复


Lenville 2018年7月29日 下午7:54

感谢勘误,前来报道

回复