读深入ES6记[一]

作者: 蛋先生DX | 来源:发表于2016-07-22 12:19 被阅读240次
ES6

划重点了,有没像期末考时老师给题目范围的感觉,呵呵。

该笔记系列主要是在阅读深入ES6系列文章时,自己印象较为深刻的部分的记录,也是自己对学习内容的一些总结,目的在于当自己有点忘却的时候,可以快速看看自己这里所写内容就可以记起大概。当然,如果正在阅读本篇文章的你们,可以通过该文章对ES6有个快速简单的了解,那就太太好了。闲话不多说,开始写写写。。。

第一章:ES6介绍

1.ECMAScript是一个程序语言标准,它描述了这门语言的语法,类型,标准库等。

2.Javascript是它的实现和扩展(微软的Jscript也是其实现和扩展)。

3.ES6就是指ECMAScript这个标准的第6版

4.文中提到ES5中引入了一些新特性,其中Object.create()让我较感兴趣,跟对象的继承实现有关系,我们看下MDN对该方法的描述:

The Object.create() method creates a new object with the specified prototype object and properties.

即通过指定原型object和属性来创建新的object,怎么用在继承实现上,代码伺候:

function Super() {
  this.name = 'super';
}
Super.prototype.sayName = function () {
  console.log(this.name);
}

function Sub() {
  Super.call(this);
}
// Sub.prototype = new Super(); // 用new的方式继承原型
Sub.prototype = Object.create(Super.prototype); // 用Object.create的方式继承原型
Sub.prototype.constructor = Sub;

Object.create()更优,因为这样的写法来继承prototype更直观易懂,而且子类的prototype不会包含多余的父类属性(如例子中的name)

有没同学会问用new的方式,子类的prototype会包含父类的属性,那这个属性会不会造成影响?
答案是不会滴,因为我们在子类的构造函数中调用了Super.call(this)来达到每个子类的实例都拥有自己的一份属性(name),而作用域是先从实例来查看该属性是否存在,不存在才去prototype查找。很明显实例中存在,所以子类中的prototype的属性其实没什么用

第二章:迭代器(Iterator)与for-of循环

1.避免for-in来遍历数组,因为它是一个坑,为啥?

坑 1

var arr = ['foo', 'bar'];
for (var idx in arr) {
  console.log(arr[idx]);
}

idx是字符串,如果你把它当数字,进行了类似这样的计算idx + 1就悲剧了,因为它的值会像这样"01","11"。
为啥它是字符串而不是数字呢?因为人家本来就设计来遍历对象的嘛,对象的key一般都是字符串嘛

坑 2

var arr= ['a', 'b'];
arr.key = 'value';
for (var idx in arr) {
  console.log(idx); // 输出"0" "1" "key"
}

for-in会遍历对象的所有可枚举的属性,包括自定义和原型中的属性,所以有些行为可能不如你所愿

2.for-of遍历数组数据的理想作法

为啥理想呢?因为它没有for-in的坑,把上面for-in的代码用for-of试一下就清楚了
还有循环中我们总是希望在某些条件下跳过或者打断循环,在for-of里面是可以通过breakcontinuereturn控制循环

3.哪些数据类型可以使用for-of

实现了迭代器接口方法([Symbol.iterator]()和next())的对象都可以使用。
内建的Array,Map,Set等自实现了迭代器接口,所以可以使用for-of
普通对象Object是不能使用for-of的,因为,来,你说一下,哈。试下这里的代码,看会报什么错:for (var val of {a: 1}) {}

4.让普通对象Object也能for-of

上面提到需要实现迭代器接口才能使用for-of来遍历数据,那我们来看看怎么让普通对象Object也能拥有此特性
注意:以下仅用于举例说明,如想用于生产环境,风险自负哈

Object.prototype[Symbol.iterator] = function() {
  return this; // 返回迭代器对象。一个迭代器必须实现了next接口,返回值格式为{done: [bool], value: }
};
Object.prototype.next = function () {
  this.currentIdx = (this.currentIdx === undefined ? -1 : this.currentIdx) + 1;
  let keys = Object.keys(this);
  let keyTotal = keys.length - 1; // 排除掉currentIdx这个属性
  let done = keyTotal < this.currentIdx + 1;
  let key = done ? null : keys[this.currentIdx];
  let value = key ? this[key] : undefined;
  return {done: done, value: value};
};

obj = {a: 1};
for (let val of obj) {
  console.log(val);
}

5.Why [Symbol.iterator]?代码不好看有木有

有没人有疑问,为啥要用[Symbol.iterator],这看上去不太优雅呀,改成iterator多好,比如Object.prototype.iterator = function() {}
制定标准的人还是考虑得很周到的,万一别人的对象已经有iterator方法呢?所以为了不造成冲突,用Symbol是个好做法(Symbol是什么东东,后面会讲到,不懂的先带着疑问看下去吧)

6.为啥用迭代器设计模式?不就遍历数据而已吗?

有思考过这个问题的人举个手呗(好吧,反正我看不到)。
有没人说数组用自己的遍历方式,Map用自己的遍历方式等就行拉。当然,可以,但只能说思想境界不同而已。
迭代器设计模式的引入是为了让调用者可以不关心数据的存储细节(Array?Map?Set?or other...),用统一的接口(比如Javascript这里用for-of)来遍历数据,而要实现遍历的对象也只需实现迭代器规定的接口即可。
常见的迭代器的接口设计有:
以Java为代表:hasNext和next方法
以Python为代表:只有next方法,无值时抛异常
以Javascript为代表:只有next方法,返回对象中用done属性来表明是否遍历完成

7.用简单等价代码理解for-of

我们以上面实现了迭代器的普通对象来继续这个话题

var obj = {a: 1};

for (let val of obj) {
  console.log(val);
}

从以下简单等价的代码可看出for-of的基本逻辑,当然,实际的for-of实现会更复杂些

var obj = {a: 1};

var iterator = obj[Symbol.iterator]();
var result = iterator.next();
while(!result.done) {
  var value = result.value;

  // 一些语句
  console.log(value);

  result = iterator.next();
}

这就是第一,二章的学习情况,接下来可继续看《读深入ES6记[二]》

--EOF--

相关文章

  • 读深入ES6记[一]

    划重点了,有没像期末考时老师给题目范围的感觉,呵呵。 该笔记系列主要是在阅读深入ES6系列文章时,自己印象较为深刻...

  • 读深入ES6记[三]

    第五章:不定参数和默认值 1.解决的问题 可用来代替arguments,解决它存在的可读性和参数索引的问题。用个栗...

  • 读深入ES6记[二]

    第三章:生成器(Generator) 1.解决的问题 当前可以总结出来的是 简化代码 和 解决回调地狱 ,举个栗子...

  • 读深入ES6记[四]

    第七章:箭头函数 1.箭头符号,悠久的历史 以下写法是不是灰常眼熟啊,但你了解为啥要这样写吗? 这是为了兼容不支持...

  • 读深入ES6记[五]

    第九章:使用Babel和Broccoli来编写ES6 1.流行的转译器 转译器,即源代码到源代码的编译器 非标准J...

  • 深入解析 ES6:Collections

    深入解析 ES6:Collections 原文链接:ES6 In Depth: Collections 前段时间,...

  • ES6 数组新用法(二)

    《深入理解ES6》阅读随笔 find() find 方法接收一个函数作为参数,用于筛选寻找数组中满足条件的第一条记...

  • 《深入理解ES6》学习笔记(第一天)

    《深入理解ES6》学习笔记(第一天) 关于本书 深入理解ES6的特性对于所有JavaScript开发人员来说至关重...

  • 读《深入理解ES6》

    第一章:块级作用域绑定 块级声明 1.var声明及变量提升机制:在函数作用域或者全局作用域中通过关键字var声明的...

  • ES6——Reflect 与 Proxy

    ES6 之 Proxy 介绍深入实践 ES6 Proxy & Reflect 1.Proxy Proxy 可以对目...

网友评论

    本文标题:读深入ES6记[一]

    本文链接:https://www.haomeiwen.com/subject/ebxijttx.html