{"action":"created","issue":{"url":"https://api.github.com/repos/ruanyf/es6tutorial/issues/81","labels_url":"https://api.github.com/repos/ruanyf/es6tutorial/issues/81/labels{/name}","comments_url":"https://api.github.com/repos/ruanyf/es6tutorial/issues/81/comments","events_url":"https://api.github.com/repos/ruanyf/es6tutorial/issues/81/events","html_url":"https://github.com/ruanyf/es6tutorial/issues/81","id":103652215,"number":81,"title":"一些问题","user":{"login":"howiefh","id":1058341,"avatar_url":"https://avatars.githubusercontent.com/u/1058341?v=3","gravatar_id":"","url":"https://api.github.com/users/howiefh","html_url":"https://github.com/howiefh","followers_url":"https://api.github.com/users/howiefh/followers","following_url":"https://api.github.com/users/howiefh/following{/other_user}","gists_url":"https://api.github.com/users/howiefh/gists{/gist_id}","starred_url":"https://api.github.com/users/howiefh/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/howiefh/subscriptions","organizations_url":"https://api.github.com/users/howiefh/orgs","repos_url":"https://api.github.com/users/howiefh/repos","events_url":"https://api.github.com/users/howiefh/events{/privacy}","received_events_url":"https://api.github.com/users/howiefh/received_events","type":"User","site_admin":false},"labels":[],"state":"closed","locked":false,"assignee":null,"milestone":null,"comments":4,"created_at":"2015-08-28T05:45:10Z","updated_at":"2015-08-28T14:40:48Z","closed_at":"2015-08-28T10:52:33Z","body":"# 勘误\r\n## [Proxy](https://github.com/ruanyf/es6tutorial/blob/gh-pages/docs/proxy.md)\r\n\r\n> Proxy对象的所用用法，都是上面这种形式，不同的只是handler参数的写法。其中，new Proxy()表示生成一个Proxy实例，target参数表示所要拦截的目标对象，handler参数也是一个对象，用来定制拦截行为。\r\n\r\n“所用用法“应该是“所有用法“\r\n\r\n> 上面代码中，proxy对象是obj对象的原型，obj对象本身并没有time属性，所有根据原型链，会在proxy对象上读取该属性，导致被拦截。\r\n\r\n“所有“应该是“所以“\r\n\r\n> Reflect对象的方法清单如下。\r\n    * Reflect.getOwnPropertyDescriptor(target,name)\r\n    * Reflect.defineProperty(target,name,desc)\r\n    * Reflect.getOwnPropertyNames(target)\r\n    * Reflect.getPrototypeOf(target)\r\n\r\nReflect对象的方法清单漏了 `Reflect.setPrototypeOf(obj, newProto)`，在清单后面的几个方法的解释中提到了这个方法\r\n\r\n## [Iterator](https://github.com/ruanyf/es6tutorial/blob/gh-pages/docs/iterator.md)\r\n\r\n> 对于类似数组的对象（存在数值键名和length属性），部署Iterator接口，有一个简便方法，就是Symbol.iterator方法直接引用数值的Iterator接口。\r\n\r\n“数值的Iterator接口“应该是“数组的Iterator接口”\r\n\r\n> ES6规定，默认的Iterator接口部署在数据结构的`Symbol.iterator`属性，或者一个数据结构只要具有`Symbol.iterator`属性，就可以认为是“可遍历的”（iterable）。也就是说，调用`Symbol.iterator`方法，就会得到当前数据结构的默认遍历器。`Symbol.iterator`本身是一个表达式，返回Symbol对象的iterator属性，这是一个预定义好的、类型为Symbol的特殊值，所以要放在方括号内（请参考Symbol一节）。\r\n\r\n感觉文中Iterable，Iterator，IteratorResult三个接口并没有明确区分，主要是前两者，比如说上面的引用段落\r\n\r\n“默认的Iterator接口“应该是[Iterable接口](http://www.ecma-international.org/ecma-262/6.0/#sec-iterable-interface)可能更合适些，其它部分也有类似表述问题。\r\n\r\n> 对数组和Set结构进行解构赋值时，会默认调用iterator接口。\r\n\r\n文中说的“调用iterator接口”表述上是不是有些不当，我觉得调用接口的方法更加合适些。\r\n\r\n上文中说调用Iterable接口的Symbol.iterator方法是不是更准确些。 或者简单说调用Symbol.iterator方法。\r\n\r\n## [Generator](https://github.com/ruanyf/es6tutorial/blob/gh-pages/docs/generator.md)\r\n\r\n> Symbol.iterator属性执行后，返回自身。\r\n\r\n属性应为方法\r\n\r\n> 上面代码中，delegatingIterator是代理者，delegatedIterator是被代理者。由于`yield* delegatedIterator`语句得到的值，是一个遍历器，所以要用星号表示。运行结果就是使用一个遍历器，遍历了多个Genertor函数，有递归的效果。\r\n\r\nGenertor 应该为 Generator\r\n\r\n> 如果遍历器函数内部没有部署try...catch代码块，那么throw方法抛出的错误，将被外部try...catch代码块捕获。\r\n\r\n这里“遍历器函数“是不是应该是“Generator 函数“\r\n\r\n> 上面代码只输出hello就结束了，因为第二次调用next方法时，遍历器状态已经变成终止了。但是，如果使用throw方法抛出错误，不会影响遍历器状态。\r\n\r\n“throw方法“应该为“throw命令“\r\n\r\n## [Promise](https://github.com/ruanyf/es6tutorial/blob/gh-pages/docs/promise.md)\r\n\r\n> 上面代码中，Promise指定在下一轮“事件循环”再抛出错误，结果由于没有指定catch语句，就冒泡到最外层，成了未捕获的错误。\r\n\r\n文中说“没有指定catch语句“，这里的“catch语句“是指try-catch语句吧，感觉容易误想成catch方法\r\n\r\n## [Class](https://github.com/ruanyf/es6tutorial/blob/gh-pages/docs/class.md)\r\n\r\n> 在ES5中，每一个对象都有`__proto__`属性，指向对应的构造函数的prototype属性。Class作为构造函数的语法糖，同时有prototype属性和`__proto__`属性，因此同时存在两条继承链。\r\n\r\n`__proto__`虽然大多数浏览器支持，但是前面章节也讲并没有加入ES6，这里这么说\"在ES5中，每一个对象都有`__proto__`属性“是不是不太合适\r\n\r\n## [Module](https://github.com/ruanyf/es6tutorial/blob/gh-pages/docs/module.md)\r\n\r\n> 然后，main.js文件输入circlek.js模块。\r\n\r\ncirclek.js 应该为 circle.js\r\n\r\n> console.log(exp(math.pi));\r\n\r\nmath.pi是不是应该是math.e\r\n\r\n# 一些疑问\r\n## [Symbol](https://github.com/ruanyf/es6tutorial/blob/gh-pages/docs/symbol.md)\r\n\r\n<http://www.ecma-international.org/ecma-262/6.0/#sec-ecmascript-language-types> 有下面的描述\r\n> The ECMAScript language types are Undefined, Null, Boolean, String, Symbol, Number, and Object.\r\n\r\n为什么[Symbol](https://github.com/ruanyf/es6tutorial/blob/gh-pages/docs/symbol.md)一章中讲的是8种数据类型？\r\n\r\n## [Class](https://github.com/ruanyf/es6tutorial/blob/gh-pages/docs/class.md)\r\n\r\n> 构造函数的prototype属性，在ES6的“类”上面继续存在。事实上，除了constructor方法以外，类的方法都定义在类的prototype属性上面。\r\n\r\nconstructor不也是prototype的一个属性吗\r\n\r\n## [Module](https://github.com/ruanyf/es6tutorial/blob/gh-pages/docs/module.md)\r\n\r\n> sfirsetHeader\r\n\r\n没明白这个函数名的意思"},"comment":{"url":"https://api.github.com/repos/ruanyf/es6tutorial/issues/comments/135792747","html_url":"https://github.com/ruanyf/es6tutorial/issues/81#issuecomment-135792747","issue_url":"https://api.github.com/repos/ruanyf/es6tutorial/issues/81","id":135792747,"user":{"login":"howiefh","id":1058341,"avatar_url":"https://avatars.githubusercontent.com/u/1058341?v=3","gravatar_id":"","url":"https://api.github.com/users/howiefh","html_url":"https://github.com/howiefh","followers_url":"https://api.github.com/users/howiefh/followers","following_url":"https://api.github.com/users/howiefh/following{/other_user}","gists_url":"https://api.github.com/users/howiefh/gists{/gist_id}","starred_url":"https://api.github.com/users/howiefh/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/howiefh/subscriptions","organizations_url":"https://api.github.com/users/howiefh/orgs","repos_url":"https://api.github.com/users/howiefh/repos","events_url":"https://api.github.com/users/howiefh/events{/privacy}","received_events_url":"https://api.github.com/users/howiefh/received_events","type":"User","site_admin":false},"created_at":"2015-08-28T14:40:48Z","updated_at":"2015-08-28T14:40:48Z","body":"阮老师，我觉得JavaScript的Iterable，Iterator，IteratorResult三个接口可以和Java中的java.lang.Iterable，java.util.Iterator 两个接口做个类比。其它一些语言也有类似的实现。\r\n\r\njava.lang.Iterable 接口\r\n```\r\npublic interface Iterable<T> {\r\n    Iterator<T> iterator();\r\n}\r\n```\r\njava.util.Iterator 接口\r\n```\r\npublic interface Iterator<E> {\r\n    boolean hasNext();\r\n    E next();\r\n    void remove();\r\n}\r\n```\r\n\r\nJava中实现Iterable接口可以使对象成为 \"foreach\" 语句的目标。像HashSet，ArrayList等类都实现了这个接口。于是就可以这样去遍历Set：\r\n\r\n```\r\nSet<String> set = new HashSet<String>();\r\nfor (String s: set){}\r\n```\r\n\r\n虽然JavaScript中没有像ES6中加入class一样加入interface关键字，但是有[类似的概念](http://www.ecma-international.org/ecma-262/6.0/#sec-common-iteration-interfaces)，JavaScript中的接口就是对某一组属性的描述，只要一个对象具有某个接口描述的所有属性就可以称其实现了这个接口。\r\n\r\n而JavaScript中的 Iterable 和 Iterator两个接口和Java中是十分相似的，Iterable接口和Java的java.lang.Iterable接口一样只包含一个方法`[Symbol.iterator]`，这个方法返回一个实现了Iterator接口的对象，而只要实现了这个接口，就可以用于`for-of`语句。JavaScript中的 Iterator接口必须有一个next方法，这个方法和Java中java.util.Iterator接口的next方法类似，只是前者用next方法返回的IteratorResult对象的done属性判断是否遍历完了，而Java中的接口使用hasNext方法判断。\r\n\r\n由此可以看出JavaScript和Java中Iterable接口很相似，实现了该接口的对象都可以在一种for-each机制中使用，而且都包含有功能类似的方法。Iterator接口也很相似，都提供了基本的next方法，用于迭代下一项。\r\n\r\n最后，作比较是想说如果更明确的说明Iterable，Iterator，IteratorResult接口的话，可以让人看后更清晰一些，知道个来龙去脉，阮老师在文中的不同场景中多次使用了遍历器、指针这样的概念，容易让人搞不清概念。\r\n\r\n[Iterator](https://github.com/ruanyf/es6tutorial/blob/gh-pages/docs/iterator.md)\r\n\r\n> 创建一个指针，指向当前数据结构的起始位置。也就是说，遍历器的返回值是一个指针对象。\r\n\r\n这里遍历器就是指Iterable的`[Symbol.iterator]`方法了，而指针对象就是Iterator对象了。\r\n\r\n> 完全可以写出没有对应数据结构的遍历器\r\n\r\n根据后面的例子，我理解这里的遍历器是指实现了Iterator接口的对象了。\r\n\r\n> 凡是部署了Symbol.iterator属性的数据结构，就称为部署了遍历器接口。\r\n\r\n这里遍历器又指Iterable接口了\r\n\r\n没有明确的说明Iterable，Iterator，IteratorResult接口而都用遍历器、指针来描述，感觉有点混乱。\r\n\r\n关于Iterator的译法，Java里译作迭代器，一些语言貌似也有相同的译法，如果别的语言中已经有了通用的译法，我觉得可以借鉴过来，也容易被理解接受。\r\n\r\n最后，非常感谢阮老师开源了这本书，从中受益颇多。"}}