初学ES6笔记一

本人的笔记内容来自于[阮一峰老师的ECMAScript 6 详细内容请看(http://es6.ruanyifeng.com/#docs/array)

## Node.js是Javascript语言的服务器运行环境。

Bebal转码器
将ES6代码转换为ES5,不用担心现有环境是否支持ES6。

*** let和const命令:

一.let命令*
1 . let 所声明的变量,只在let命令所在的代码块内有效
for循环的计数器,就很合适使用let命令 for(let I=0;i<10;i++){}
只要块级作用域内存在let命令,它所声明的变量就“绑定”(binding)这个
区域,不再受外部的影响
ES6 明确规定,如果区块中存在let和const命令,这个区块对这些命令声
明的变量,从一开始就形成了封闭作用域。凡是在声明之前就使用这些变
量,就 会报错。

总之,在代码块内,使用let命令声明变量之前,该变量都是不可用的。这 在语法上,称为**“暂时性死区**”(temporal dead zone,简称 TDZ
let不允许在相同作用域内,重复声明同一个变量。
2.块级作用域
没有块级作用域,带来以下不便:
第一种场景:内层变量可能会覆盖外层变量。
第二种场景:用来计数的循环变量泄漏为全局变量。

         eg:   
            var s='hello';
                for(var i=0;i<s.length;i++){
                 console.log(s[i]);
                   }
                   console.log[i];//输出结果为5
                   变量只是用来控制循环,但是循环结束后,它并没有消失,从而泄  
                   漏了全局变量。

ES6允许块级作用域任意嵌套 外层作用域无法影响内层作用域
内层作用域可以定义外层作用域同名的变量

eg:     function(){console.log('I am outside!');}
          (function(){
          if(false)
                function f(){console.log('I am inside!')}
                }
                f();
          }());
          此代码在ES5中运行,得到I am inside!,在ES6中得到I am outside!。
          因为在ES5中存在函数提升,不管会不会进入if代码块,函数都会提升到当前作用域的顶部而得到执行;而ES6支持块级作用域,不管会不会进入if代码块,其内部函数声明都不会影响到作用域的外部。

二.const命令*
const声明一个只读的常量。一旦声明,常量的值就不能改变。const声明的变量不得改变值,这意味着,const一旦声明变量,就必须立即初始化,不能留到以后赋值。
const的作用域与let命令相同:只在声明所在的块级作用域内有效。
const命令声明的常量也是不提升,同样存在暂时性死区,只能在声明
的位置后面使用。
const声明的常量,也与let一样不可重复声明。
如果真的想将对象冻结,应该使用Object.freeze方法。
全局环境中,this会返回顶层对象。但是,Node 模块和 ES6 模块中,this 返回的是当前模块。函数里面的this,如果函数不是作为对象的方法运行,而
是单纯作为函数运行,this会指向顶层对象。
对于复合型的变量,变量名不指向数据,而是指向数据所在的地址。const命令指示保证变量名指向的地址不改变,并不保存该地址的数据不变。
eg:

const foo={};常量foo存储的是一个地址,指向一个对象,既不能把foo指向 
                 另一个地址,但是对象本身是可变的,可以为其添加新属性         
          foo.prop=123;
         foo.prop//123
          foo={}//TypeError:'foo' is read-only不起作用

三.变量的解构赋值
1.数组的解构赋值
‘模式匹配’,只要等号两边相同左边的变量就会被赋予对应的值
eg:

var[a,b,c]=[1,[[2],3]]    解构不成功,变量的值就等于undefined
      默认值:解构赋值允许指定默认值
           eg:var[foo=true]=[];
           foo;//true

2.对象的解构赋值
解构不仅可以用于数组,还可以用于对象
eg:

  var {foo,bar}={foo:'aaa',bar:'bbbb'};
             foo//'aaa'
             bar//'bbb'
    对象的属性没有次序,变量名必须与属性名相同,才能取到正确的值。
变量名与属性名不同,需要写成下面这样:
eg: 
var{foo:baz}={foo:'aaa',bar:'bbb'};
       baz//'aaa'
对象的解构赋值的内部机制,是先找到同名属性,然后再赋给对应的变量。真正被赋值的是后者,而不是前者。
let { foo: baz } = { foo: "aaa", bar: "bbb" };
这种写法是变量和赋值一起进行,一旦赋  值的变量以前声明过,就会报错        
baz // "aaa"         
foo // error: foo is not defined

四.字符串的解构赋值

字符串也可以解构赋值。这是因为此时,字符串被转换成了一个类似数组的对象。
const [a, b, c, d, e] = 'hello';
a // "h"
b // "e"
c // "l"
d // "l"
e // "o"
类似于数组的对象都有length属性,因此还可以对这个属性解构赋值
let{length:len}='Hello';
len//5

五.数值和布尔值的解构赋值

如果等号右边是数值或布尔值,则会先转为对象。
let{toString:s}=123;
s===Number.prototype.toString//true
let{toString:s}==true;
s===Boolean,prototype,toString//true
由于null和undefined无法转成对象,所以会报错
let{prop:x}=undefined;//TypeError
let{prop:y}=null;//TypeError

五.函数参数的解构赋值

函数参数的解构也可以使用默认值。
function move({x = 0, y = 0} = {}) {
  return [x, y];
}

move({x: 3, y: 8}); // [3, 8]
move({x: 3}); // [3, 0]
move({}); // [0, 0]
move(); // [0, 0]
上面代码中,函数move的参数是一个对象,通过对这个对象进行解构,得到变量x和y的值。如果解构失败,x和y等于默认值。

注意,下面的写法会得到不一样的结果。
function move({x, y} = { x: 0, y: 0 }) {
  return [x, y];
}
move({x: 3, y: 8}); // [3, 8]
move({x: 3}); // [3, undefined]
move({}); // [undefined, undefined]
move(); // [0, 0]
上面代码是为函数move的参数指定默认值,而不是为变量x和y指定默认值,所以会得到与前一种写法不同的结果。

五.圆括号问题
不能使用圆括号的情况:
1.变量声明语句中,模式不能带有括号。

var [(a)=[1]];//报错
var {x:(c)}={};//报错
var {o:({p:p})}={o:{p:2}}//报错

2.函数参数中,模式不能带有括号。
函数参数也属于变量声明,所以不能带括号

function([[(z)]){return z;}//报错

3.不能将整个模式或嵌套模式中的一层放在圆括号中。

({ p: a }) = { p: 42 };// 报错
([a]) = [5];// 报错

上面代码将整个模式放在圆括号之中,导致报错。

[({ p: a }), { x: c }] = [{}, {}];// 报错

上面代码将一部分模式放在圆括号之中,导致报错。

可以使用圆括号的情况:

只有一种情况下可以使用圆括号:赋值语句的非模式部分可以使用圆括号。
[(b)]=[3];//正确
({p:(d)}={});//正确
[(parseInt.prop)]=[3];//正确

首先它们都是赋值语句,而不是声明语句;其次它们的圆括号都不属于模式的一部分。第一行语句中,模式是取数组的第一个成员,跟圆括号无关;第二行语句中,模式是p,而不是d;第三行语句与第一行语句的性质一致。

五.用途
(1)交换变量的值 [x, y] = [y, x];
(2)从函数返回多个值
函数只能返回一个值,如果要返回多个值,只能将它们放在数组或对象里返回。有了解构赋值,取出这些值就非常方便。
(3)函数参数的定义
解构赋值可以方便地将一组参数与变量名对应起来。
(4)提取 JSON 数据
解构赋值对提取 JSON 对象中的数据,尤其有用。
(5)函数参数的默认值

指定参数的默认值,就避免了在函数体内部再写var foo = config.foo || ‘default foo’;这样的语句。
(6)遍历 Map 结构
任何部署了 Iterator 接口的对象,都可以用for…of循环遍历。Map 结构原生支持 Iterator 接口,配合变量的解构赋值,获取键名和键值就非常方便。
(7)输入模块的指定方法
加载模块时,往往需要指定输入哪些方法。解构赋值使得输入语句非常清晰。

const { SourceMapConsumer, SourceNode } = require("source-map");

猜你喜欢

转载自blog.csdn.net/weixin_44072887/article/details/88656024