├── .gitattributes
├── .idea
├── ES6-learn.iml
├── jsLibraryMappings.xml
├── misc.xml
├── modules.xml
├── vcs.xml
├── watcherTasks.xml
└── workspace.xml
├── Array.js
├── README.md
├── es6-one-day.js
├── git.js
├── let-and-const.js
├── promise.js
└── set-or-map.js
/.gitattributes:
--------------------------------------------------------------------------------
1 | # Auto detect text files and perform LF normalization
2 | * text=auto
--------------------------------------------------------------------------------
/.idea/ES6-learn.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/.idea/jsLibraryMappings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.idea/watcherTasks.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/.idea/workspace.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 | true
90 | DEFINITION_ORDER
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
154 |
155 |
156 |
157 |
158 |
159 |
160 |
161 |
162 |
163 |
164 |
165 |
166 |
167 |
168 |
169 |
170 |
171 |
172 |
173 |
174 |
175 |
176 |
177 |
178 |
179 |
180 |
181 |
182 |
183 |
184 |
185 |
186 |
187 |
188 |
189 |
190 | project
191 |
192 |
193 |
194 |
195 |
196 |
197 |
198 |
199 |
200 |
201 |
202 |
203 |
204 |
205 |
206 | project
207 |
208 |
209 | true
210 |
211 |
212 |
213 | DIRECTORY
214 |
215 | false
216 |
217 |
218 |
219 |
220 |
221 |
222 |
223 |
224 |
225 |
226 |
227 |
228 |
229 |
230 |
231 |
232 |
233 |
234 |
235 |
236 |
237 |
238 | 1508315766383
239 |
240 |
241 | 1508315766383
242 |
243 |
244 |
245 |
246 |
247 |
248 |
249 |
250 |
251 |
252 |
253 |
254 |
255 |
256 |
257 |
258 |
259 |
260 |
261 |
262 |
263 |
264 |
265 |
266 |
267 |
268 |
269 |
270 |
271 |
272 |
273 |
274 |
275 |
276 |
277 |
278 |
279 |
280 |
281 |
282 |
283 |
284 |
285 |
286 |
287 |
288 |
289 |
290 |
291 |
292 |
293 |
294 |
295 |
296 |
297 |
298 |
299 |
300 |
301 |
302 |
303 |
304 |
305 |
306 |
307 |
308 |
309 |
310 |
311 |
312 |
313 |
314 |
315 |
316 |
317 |
318 |
319 |
320 |
321 |
322 |
323 |
324 |
325 |
326 |
327 |
328 |
329 |
330 |
331 |
332 |
333 |
334 |
335 |
336 |
337 |
338 |
339 |
340 |
341 |
342 |
343 |
344 |
345 |
346 |
347 |
348 |
349 |
350 |
351 |
352 |
353 |
354 |
355 |
356 |
357 |
358 |
359 |
360 |
361 |
362 |
363 |
364 |
365 |
366 |
367 |
368 |
369 |
370 |
371 |
372 |
373 |
374 |
375 |
376 |
377 |
378 |
379 |
380 |
381 |
382 |
383 |
384 |
385 |
386 |
387 |
388 |
389 |
390 |
391 |
392 |
393 |
394 |
395 |
396 |
397 |
398 |
399 |
400 |
401 |
402 |
403 |
404 |
405 |
406 |
407 |
408 |
409 |
410 |
411 |
412 |
413 |
414 |
415 |
416 |
417 |
418 |
419 |
420 |
421 |
422 |
423 |
424 |
425 |
426 |
427 |
428 |
429 |
430 |
431 |
432 |
433 |
434 |
435 |
436 |
437 |
438 |
439 |
440 |
441 |
442 |
443 |
444 |
445 |
446 |
447 |
448 |
449 |
450 |
451 |
452 |
453 |
454 |
455 |
456 |
457 |
458 |
459 |
460 |
461 |
462 |
463 |
464 |
465 |
466 |
467 |
468 |
469 |
470 |
471 |
472 |
473 |
474 |
475 |
476 |
--------------------------------------------------------------------------------
/Array.js:
--------------------------------------------------------------------------------
1 | //ES6数组的扩展
2 | //Array.from()
3 |
4 | //下面是一个类的对象
5 | let arrayLike = {
6 | '0': 'a',
7 | '1': 'b',
8 | '2': 'c',
9 | length: 3
10 | };
11 |
12 | //ES5的写法
13 | var arr1 = [].slice.call(arrayLike);
14 |
15 | //ES6的写法
16 | let arr2 = Array.from(arrayLike);
17 |
18 | //常见的类似数组的对象是DOM操作返回的NodeList集合,
19 | //以及函数内部的arguments对象。Array.from都可以将它们转为真正的数组。
20 |
21 | //NodeList 对象
22 | let ps = document.querySelectorAll('p');
23 | Array.from(ps).forEach(function(p) {
24 | console.log(p);
25 | })
26 |
27 | // arguments对象
28 | function foo() {
29 | var args = Array.from(arguments);
30 | // ...
31 | }
32 |
33 | //只要是部署了Iterator接口的数据结构,Array.from都能将其转为数组。
34 | Array.from('hello');
35 | //['h', 'e', 'l', 'l', 'o']
36 |
37 | let namesSet = new Set(['a', 'b']);
38 | Array.from(namesSet);
39 | //字符串和Set结构都具有Iterator接口,因此可以被Array.from转为真正的数组。
40 |
41 | Array.from(1, 2, 3);
42 |
43 | //扩展运算符(...)也可以将某些数据结构转为数组。
44 | //arguments
45 | function foo() {
46 | var args = [...arguments];
47 | }
48 | Array.from({ length: 3 });
49 | // [ undefined, undefined, undefined ]
50 |
51 | const toArray = (() => {
52 | Array.form ? Array.form : obj => [].slice.call(obj);
53 | })();
54 |
55 | //Array.form 还可以接收第二个参数 类似于数组的map方法
56 |
57 | Array.form(arrayLike, x => x * x);
58 |
59 | //等同于
60 |
61 | Array.form(arrayLike).map(x => x * x);
62 |
63 | Array.form([1, 2, 3], (x) => x * x);
64 |
65 | //[1,4,9]
66 |
67 | //获取dom
68 |
69 | let spans = document.querySelectorAll(span.name);
70 |
71 | //map()
72 | let names1 = Array.prototype.map.call(spans, s => s.textContent);
73 |
74 | //Array.form
75 | let names2 = Array.form(spans, s => s.s.textContent);
76 |
77 | //Array.form() 将数组转成false的成员转为0
78 | Array.form([1, 2, 3], (n) => n || 0);
79 | console.log(n);
80 |
81 | Array() // []
82 | Array(3) // [, , ,]
83 | Array(3, 11, 8) // [3, 11, 8]
84 |
85 | //Array.of总是返回参数值组成的数组。如果没有参数,就返回一个空数组。
86 |
87 | function ArrayOf() {
88 | return [].slice.call(arguments);
89 | }
90 |
91 |
92 | //数组实例的copyWithin()
93 | Array.prototype.copyWithin(target, start = 0, end = this.length);
94 |
95 | [1, 2, 3, 4, 5].copyWithin(0, 3);
96 | //4 5 3 4 5
97 |
98 | // 将3号位复制到0号位
99 | [1, 2, 3, 4, 5].copyWithin(0, 3, 4)
100 | // [4, 2, 3, 4, 5]
101 |
102 | //数组实例的find()和findIndex()
103 | //数组中找出小于零的
104 | [1, 4, -5, 10].find((n) => n < 0)
105 | console.log([1, 4, -5, 10].find((n) => n < 0));
106 |
107 | [1, 5, 10, 15].find(function(value, index, err) {
108 | return value > 9;
109 | })
110 | console.log([1, 5, 10, 15].find(function(value, index, err) {
111 | return value > 9;
112 | })) //10
113 |
114 | //findindex()返回符合条件的数组成员位置
115 | [1, 5, 10, 15].findIndex(function(value, inidex, err) {
116 | return value > 9
117 | })
118 |
119 | //fill()
120 | //fill方法给定值 填充数组
121 | ['a', 'b', 'c'].fill(7);
122 |
123 | let min = 14.1;
124 | let eaiml = "hzl.shenwei@gmail.com";
125 |
126 | let arrData = [
127 | {
128 | name : "111",
129 | arr:[
130 | {
131 | name:'333',
132 | children:[
133 | {
134 | name:'yyy'
135 | }
136 | ]
137 | }
138 | ]
139 | },
140 | { name : "311" },
141 | { name : "11" },
142 | { name : "111" },
143 | { name : "111" },
144 | ]
145 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | 根据ES6文档学习...
2 | =====================
3 |
4 |
5 |
--------------------------------------------------------------------------------
/es6-one-day.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Created by Administrator on 2017/10/18.
3 | */
4 | //ES6编程风格
5 |
6 | //1、块级作用域
7 | //let 取代 var
8 | 'use strict';
9 | if(true){
10 | let x = 'hello';
11 | }
12 | for(let i = 0; i<10; i++){
13 | console.log(i);
14 | }
15 | //var 命令存在变量提升效用 let命令没有这个问题
16 | 'use strict';
17 | if(true){
18 | //console.log(x);
19 | let x = 'word'; //如果用var console.log()就不会报错 而是undefined
20 | }
21 | //使用const 有利于提升程序的运行效率
22 |
23 | var a = 1,b=2,c= 3;
24 | //good
25 | const a = 1;
26 | const b = 2;
27 | const c = 3;
28 |
29 | //best
30 | const [a,b,c] = [1,2,3];
31 | //const声明的是常用 有利防止无意间改变量值导致错误
32 |
33 | // 字符串 静态使用单引号 或者小撇号 不使用双引号 动态一律小撇
34 | //bad
35 | const a ="foobar";
36 |
37 | //acceptable
38 | const c = `foobar`;
39 |
40 | //good
41 | const a = `foobar`;
42 | const b = `foo{a}bar`;
43 |
44 | //解构赋值
45 | //使用数组成员对变量赋值 优先使用解构赋值
46 | const arr = [1,2,3,4];
47 |
48 | //错误的
49 | const first = arr[0];
50 | const second = arr[1];
51 |
52 | //good
53 | const [first,second] = arr;
54 |
55 | //函数的参数如果也事对象成员 也解构
56 | //bad
57 | function getFullName(user) {
58 | const firstName = user.firstName;
59 | const lastName = user.lastName;
60 | }
61 |
62 | //good
63 | function getFullName(obj) {
64 | const { firstName,lastName } = obj;
65 | }
66 |
67 | //best
68 | function getFullName({firstName, lastName}) {
69 |
70 | }
71 |
72 | //返回多个值 依然对象解构fuzhi
73 | //bad
74 | function processInput(input) {
75 | return [left,right,top,bottom];
76 | }
77 |
78 | //good
79 | function processInput(input) {
80 | return { left,right,top,bottom };
81 | }
82 |
83 | const {left,right} = processInput(input);
84 |
85 | //定义对象 单行不能逗号结尾 多行以逗号结尾
86 | //错误写法
87 | const a ={ k1:v1,k2:v2,};
88 | const b = {
89 | k1:v1,
90 | k2:v2
91 | }
92 |
93 | //good code
94 | const a ={ k1:v1,k2:v2};
95 | const b = {
96 | k1:v1,
97 | k2:v2,
98 | }
99 | //对象尽量静态化,一旦定义,就不得随意添加新的属性。如果添加属性不可避免,要使用Object.assign方法。
100 |
101 | //错误
102 | const a ={};
103 | a.x= 3;
104 |
105 | //如果要添加
106 | const a = {};
107 | Object.assign(a,{x:2});
108 |
109 | //good
110 | const a = { x:null };
111 | a.x = 3;
112 |
113 | //如果是动态的 使用属性表达式定义
114 | //bad
115 | const obj = {
116 | id:5,
117 | name:'mary',
118 | };
119 | obj[getKey('emable')] = true;
120 | //good
121 | const obj ={
122 | id:2,
123 | name:'getbum',
124 | [getKey('hhehh')]:true
125 | }
126 |
127 | //对象的属性和方法 尽量采用简洁表达方法
128 | //如
129 | var ref = 'some value';
130 |
131 | //bad
132 | const atom = {
133 | ref:ref,
134 | value:1,
135 | addValue:function (value) {
136 | return atom.value+value;
137 | },
138 | };
139 |
140 | //good
141 | const atom = {
142 | ref,
143 | value:1,
144 | addValue(value){
145 | return atom.value+value;
146 | },
147 | };
148 |
149 | //拷贝数组
150 | //bad
151 | const len = items.length;
152 | const itemsCopy = [];
153 |
154 | let i;
155 |
156 | for(i = 0; i{
169 | console.log('hello word');
170 | })();
171 |
172 | //需要函数表达式的场景 用箭头函数
173 |
174 | //bad
175 | [1,2,3].map(function (x) {
176 | return x*x ;
177 | });
178 |
179 | //good
180 | [1,2,3].map((x)=>{
181 | return x*x ;
182 | });
183 |
184 | //best
185 | [1,2,3].map(x=>x*x);
186 |
187 | //箭头函数取代Function.prototype.bid 不再用that之类绑定this
188 | //bad
189 | const self = this;
190 | const boundMethod = function (...params) {
191 | return method.apply(self,params);
192 | }
193 |
194 | //accepable
195 | const boundMethod = method.bind(this);
196 |
197 | //best
198 | const boundMethod = (...params)=>method.apply(this,params);
199 |
200 | //简单的、单行的、不会复用的函数,建议采用箭头函数。
201 | // 如果函数体较为复杂,行数较多,还是应该采用传统的函数写法。
202 |
203 | //bad
204 | function divide(a, b, option = false) {
205 |
206 | }
207 |
208 | //good
209 | function divide(a, b, {option = false} = {}) {
210 |
211 | }
212 | //不要在函数体内使用arguments变量,使用rest运算符(...)代替
213 | //bad
214 | function concatenateAll() {
215 | const args = Array.prototype.slice.call(arguments);
216 | return args.join('');
217 | }
218 |
219 | //good
220 | function concatenateAll(...args) {
221 | return args.join('');
222 | }
223 |
224 | //设置函数参数的默认值
225 | //bad
226 | function handleThings(opts) {
227 | opts = opts || {};
228 | }
229 |
230 | //good
231 | function handleThings(opts = {}) {
232 | //...
233 | }
234 |
235 | //Map 结构
236 | //它內建有遍历机制
237 | let map = new Map(arr);
238 |
239 | for(let key of map.keys()){
240 | console.log(key);
241 | }
242 |
243 | for(let value of map.value()){
244 | console.log(value);
245 | }
246 |
247 | for(let item of map.entries()){
248 | console.log(item[0],item[1]);
249 | }
250 |
251 | //用class取代prototype的操作 写法更简洁 姿势更帅
252 | //bad
253 | function Queue(contents = []) {
254 | this._queue = [...contents];
255 | }
256 | Queue.prototype.pop = function () {
257 | const value = this._queue[0];
258 | this._queue.slice(0,1);
259 | return value;
260 | }
261 |
262 | //good
263 | class Queue{
264 | constructor(contents = []){
265 | this._queue = [...contents];
266 | }
267 | pop(){
268 | const value = this._queue[0];
269 | this._queue.slice(0,1);
270 | return value;
271 | }
272 | }
273 |
274 | //使用extend实现继承
275 |
276 | //bad
277 | const inherits = require('inherits');
278 | function PeekableQueue(contents) {
279 | Queue.apply(this,contents);
280 | }
281 | inherits(PeekableQueue,Queue);
282 | PeekableQueue.prototype.peek = function () {
283 | return this._queue[0];
284 | }
285 |
286 | //good
287 | class PeekableQueue extends Queue{
288 | peek(){
289 | return this._queue[0];
290 | }
291 | }
292 | //模块
293 | //module语法是JavaScript模块的标准写法 坚持使用这种写法
294 | //使用import取代require
295 |
296 | //bad
297 | const moduleA = require('moduleA');
298 | const func1 = moduleA.func1;
299 | const func2 = moduleA.func2;
300 |
301 | //import
302 | import { func1 , func2 } from 'moduleA';
303 |
304 | //使用export取代module.exports
305 |
306 | //commonJS的写法
307 | var React = require('react');
308 |
309 | var Breadcrumbs = React.createClass({
310 | render(){
311 | return '';
312 | }
313 | });
314 |
315 | module.exports = Breadcrumbs;
316 |
317 | //ES6的写法
318 | import React from 'react';
319 |
320 | const Breadcrumbs = React.createClass({
321 | render(){
322 | return '';
323 | }
324 | });
325 |
326 | export default Breadcrumbs;
327 |
328 | //不要在模块输入中使用通配符
329 | //bad
330 | import * as myObject from './importModule';
331 |
332 | //good
333 | import myObject from './importModule';
334 |
335 | //如果函数默认输出一个函数 函数名首字母应该小写
336 | function makeStyleGuide(){
337 |
338 | }
339 | export default makeStyleGuide;
340 |
341 | //如果函数默认一个对象 函数首字母应该大写
342 | const StyleGuide = {
343 | es6:{
344 |
345 | }
346 | };
347 | export default StyleGuide;
348 |
349 | //ESLint的使用
350 | //他是一个语法规则和代码风格的检查工具 可以用来确保语法正确
351 | //安装
352 | //$ npm i -g eslint
353 |
354 | //然后安装Airbnb语法规则
355 |
356 | //$ npm i -g eslint-config-airbnb
357 |
358 | //最后,在项目的根目录下新建一个.eslintrc文件,配置ESLint。
359 |
360 | {
361 | //"extends": "eslint-config-airbnb"
362 | }
363 | //现在就可以检查,当前项目的代码是否符合预设的规则。
364 |
365 | //index.js文件的代码如下。
366 |
367 | var unusued = 'I have no purpose!';
368 |
369 | function greet() {
370 | var message = 'Hello, World!';
371 | alert(message);
372 | }
373 |
374 | greet();
375 |
376 | //原文件有三个错误,一个是定义了变量,却没有使用,另外两个是行首缩进为4个空格,而不是规定的2个空格。
377 |
378 |
379 |
380 |
381 |
382 |
383 |
384 |
385 |
386 |
387 |
388 |
389 |
390 |
391 |
392 |
393 |
394 |
395 |
396 |
397 |
398 |
399 |
400 |
401 |
402 |
403 |
404 |
405 |
406 |
407 |
408 |
409 |
410 |
411 |
412 |
413 |
414 |
415 |
416 |
417 |
418 |
419 |
420 |
421 |
422 |
423 |
424 |
425 |
426 |
427 |
428 |
429 |
430 |
431 |
432 |
433 |
434 |
435 |
436 |
437 |
438 |
--------------------------------------------------------------------------------
/git.js:
--------------------------------------------------------------------------------
1 | let obj1 = function(){
2 |
3 | }
4 |
5 |
--------------------------------------------------------------------------------
/let-and-const.js:
--------------------------------------------------------------------------------
1 | //let只在其所在代码块有效 var 不是
2 | //let严格 var垃圾
3 | {
4 | let a = 10 ;
5 | var b = 1;
6 | }
7 | //console.log(b); //1
8 | //console.log(a); //ReferenceError: a is not defined
9 |
10 | //for循环 很适合用let命令
11 | for (let i = 0; i< 10 ;i++){ }
12 | console.log(i); //ReferenceError: i is not defined
13 | //i只在for循环体内有效,在循环体外引用就会报错。
14 |
15 | //用var
16 | var a = [];
17 | for(var i = 0 ; i<10; i++){
18 | a[i] = function () {
19 | console.log(i);
20 | }
21 | }
22 | a[6](); // 10
23 | //i 是全局的 以致每次循环新的i都会覆盖旧的i 导致输出的是最后一轮的i
24 | //如果是let
25 | var b = [];
26 | for(let i = 0 ; i<10 ; i++){
27 | b[i] = function () {
28 | console.log(i);
29 | }
30 | }
31 | b[6](); //6
32 | //变量i是let声明的,当前的i只在本轮循环有效,所以每一次循环的i其实都是一个新的变量
33 |
34 | //let 不存在声明提前
35 | //var
36 |
37 | console.log(foo);
38 | //console.log(bar);
39 |
40 | var foo = 3; //undefined
41 | let bar = 3; //ReferenceError: bar is not defined
42 |
43 | //只要块级作用域存在let命令 它所声明的变量就绑定在这个区域 不受外部影响
44 | var tmp = 123;
45 | if(true){
46 | //tmp = 'abc';//ReferenceError: tmp is not defined
47 | //let tmp;
48 | }
49 | //局部干掉了全局 tmp 被声明提前 所以报错
50 |
51 | //在代码块内,使用let命令声明变量之前,该变量都是不可用的。
52 | // 这在语法上,称为“暂时性死区”(temporal dead zone,简称TDZ)。
53 | if (true){
54 | //TDZ开始
55 | //tmp = 'abc';// ReferenceError
56 | //console.log(tmp);// ReferenceError
57 |
58 | let tmp ;//TDZ结束
59 | console.log(tmp); //undefined
60 |
61 | tmp = 124;
62 | console.log(tmp); //124
63 | }
64 | //在let命令声明变量tmp之前,都属于变量tmp的“死区”。
65 |
66 | /*function bar(x = y, y = 2) {
67 | return [x, y];
68 | }*/
69 |
70 | //bar(); // 报错
71 |
72 | //是因为参数x默认值等于另一个参数y,而此时y还没有声明,属于”死区“。
73 | // 如果y的默认值是x,就不会报错,因为此时x已经声明了。
74 | function dis(x = 2, y = x) {
75 | return [x, y];
76 | }
77 | dis();
78 |
79 | //不允许重复声明
80 | //let 不允许在相同的作用域内 重复声明一个变量
81 |
82 | //报错
83 | // function() {
84 | // let a = 10;
85 | // var a = 1;
86 | //}
87 |
88 | //报错
89 | /*function () {
90 | let a = 10;
91 | let a = 1;
92 | }*/
93 |
94 | //因此 不能在函数内部重新声明参数
95 | /*function func(arg) {
96 | let arg; //报错
97 | }*/
98 | function func(arg) {
99 | {
100 | let arg; //不报错
101 | }
102 | }
103 |
104 | //块级作用域
105 | //为什么需要
106 | //ES5只有全局作用域和函数作用域 没有块级作用域者带来很多不合理的场景
107 | //第一种场景 内层变量可能会覆盖外层变量
108 |
109 | var tmp = new Date();
110 |
111 | function f() {
112 | console.log(tmp);
113 | if(false){
114 | var tmp = "hello word";
115 | }
116 | }
117 | f() //undefinde
118 | //原因在于变量提升 导致内层的tmp覆盖外层的
119 |
120 | //第二种场景 用来计数的循环变量泄露为全局变量
121 |
122 | var s = 'hello';
123 | for(var i = 0; i {
338 | Object.freeze(obj);
339 | Object.keys(obj).forEach( (key, value) => {
340 | if ( typeof obj[key] === 'object' ) {
341 | constantize( obj[key] );
342 | }
343 | });
344 | };
345 |
346 | //ES5只有两种声明变量的方法:var命令和function命令。
347 | // ES6除了添加let和const命令,后面章节还会提到,
348 | // 另外两种声明变量的方法:import命令和class命令。所以,ES6一共有6种声明变量的方法。
349 | window.a = 1;
350 | a //1
351 |
352 | a = 2;
353 | window.a //2
354 | //顶层对象的属性赋值与全局变量的赋值,是同一件事。
355 | //顶层对象的属性赋值与全局变量挂钩 被认为是JavaScript语言最大的设计败笔之一
356 | //这样的设计带来了几个很大的问题,
357 | // 首先是没法在编译时就报出变量未声明的错误,只有运行时才能知道(因为全局变量可能是顶层对象的属性创造的,而属性的创造是动态的);
358 | // 其次,程序员很容易不知不觉地就创建了全局变量(比如打字出错);
359 | // 最后,顶层对象的属性是到处可以读写的,这非常不利于模块化编程。
360 | // 另一方面,window对象有实体含义,指的是浏览器的窗口对象,顶层对象是一个有实体含义的对象,也是不合适的。
361 |
362 | //ES6为了改变这一点,一方面规定,为了保持兼容性,var命令和function命令声明的全局变量,依旧是顶层对象的属性;
363 | // 另一方面规定,let命令、const命令、class命令声明的全局变量,不属于顶层对象的属性。
364 | // 也就是说,从ES6开始,全局变量将逐步与顶层对象的属性脱钩。
365 |
366 | var a = 3;
367 | // 如果在Node的REPL环境,可以写成global.a
368 | // 或者采用通用方法,写成this.a
369 | window.a // 1
370 |
371 | let b = 1;
372 | window.b // undefined
373 | //全局变量a由var命令声明,所以它是顶层对象的属性;
374 | // 全局变量b由let命令声明,所以它不是顶层对象的属性,返回undefined。
375 |
376 | //很难找到一种方法,可以在所有情况下,都取到顶层对象。下面是两种勉强可以使用的方法。
377 |
378 | // 方法一
379 | (typeof window !== 'undefined'
380 | ? window
381 | : (typeof process === 'object' &&
382 | typeof require === 'function' &&
383 | typeof global === 'object')
384 | ? global
385 | : this);
386 | // 方法二
387 | var getGlobal = function () {
388 | if (typeof self !== 'undefined') { return self; }
389 | if (typeof window !== 'undefined') { return window; }
390 | if (typeof global !== 'undefined') { return global; }
391 | throw new Error('unable to locate global object');
392 | };
393 | //现在有一个提案,在语言标准的层面,引入global作为顶层对象。也就是说,在所有环境下,global都是存在的,都可以从它拿到顶层对象。
394 |
395 | //垫片库system.global模拟了这个提案,可以在所有环境拿到global。
396 |
397 | // CommonJS的写法
398 | require('system.global/shim')();
399 |
400 | // ES6模块的写法
401 | import shim from 'system.global/shim'; shim();
402 | //上面代码可以保证各种环境里面,global对象都是存在的。
403 |
404 | // CommonJS的写法
405 | var global = require('system.global')();
406 |
407 | // ES6模块的写法
408 | import getGlobal from 'system.global';
409 | const global = getGlobal();
410 |
411 |
412 |
413 |
414 |
415 |
416 |
417 |
418 |
419 |
420 |
421 |
422 |
423 |
424 |
425 |
426 |
427 |
428 |
429 |
430 |
431 |
432 |
433 |
434 |
435 |
436 |
437 |
438 |
439 |
440 |
441 |
442 |
443 |
444 |
445 |
446 |
447 |
448 |
449 |
450 |
451 |
452 |
453 |
454 |
455 |
456 |
457 |
458 |
459 |
460 |
461 |
462 |
463 |
464 |
465 |
466 |
467 |
468 |
469 |
470 |
471 |
472 |
473 |
474 |
--------------------------------------------------------------------------------
/promise.js:
--------------------------------------------------------------------------------
1 | var promise = new Promise(function(resolve, reject) {
2 | // ... some code
3 |
4 | if (11/* 异步操作成功 */
5 | ){
6 | resolve(value);
7 | } else {
8 | reject(error);
9 | }
10 | });
11 |
12 | var getJSON = function(url) {
13 | var promise = new Promise(function(resolve, reject){
14 | var client = new XMLHttpRequest();
15 | client.open("GET", url);
16 | client.onreadystatechange = handler;
17 | client.responseType = "json";
18 | client.setRequestHeader("Accept", "application/json");
19 | client.send();
20 |
21 | function handler() {
22 | if (this.readyState !== 4) {
23 | return;
24 | }
25 | if (this.status === 200) {
26 | resolve(this.response);
27 | } else {
28 | reject(new Error(this.statusText));
29 | }
30 | };
31 | });
32 |
33 | return promise;
34 | };
35 |
36 | getJSON("/posts.json").then(function(json) {
37 | console.log('Contents: ' + json);
38 | }, function(error) {
39 | console.error('出错了', error);
40 | });
--------------------------------------------------------------------------------
/set-or-map.js:
--------------------------------------------------------------------------------
1 | var s = new Set();
2 |
3 | [2,3,4,5,2,2].map(x=>s.add(x));
4 |
5 | //deng tong
6 | for(let i of s){
7 | console.log(i)
8 | }
9 |
10 | //2354
--------------------------------------------------------------------------------