ES6学习手稿之基本类型扩展

发布时间:2019-08-09 发布网站:脚本宝典
脚本宝典收集整理的这篇文章主要介绍了ES6学习手稿之基本类型扩展脚本宝典觉得挺不错的,现在分享给大家,也给大家做个参考。

前言

ES6标准以及颁布两年了,但是,好像还没有完全走进我们的日常开发。这篇文章从ES6的基本类型扩展入手,逐步展开对ES6的介绍。

ECMAScript和JavaScript

JavaScript是由NetscaPE创造的,该公司1996年11月将JavaScript语言提交国际标准化组织ECMA。于是ECMA次年就发布了ECMAScript 1.0版本。之所以不采用JavaScript命名,原因有两个,一个是版权问题,另一个也是想通过ecmascript表明制定者是ECMA而非Netscape。当然,这不是我们关注的重点。

1998年,发布了ECMAScript 2.0,1999年发布了ECMAScript 3.0。这是ECMAScript自颁布以来最广为支持的版本,我们现在所使用的JavaScript语法和规定大部分都来于这个版本。它是一个通用标准,奠定了JavaScript的基本语法。2000年后,4.0开始提上日程,但是由于各方分歧很大,导致4.0草案流产,只在最后发布了一个小的改进版本,即ES 3.1,不久后更名为ECMAScript 5.0。

2011年,ECMAScript 5.1版发布后,就开始制定6.0版了。2015年6月发布了ES6的第一个版本,正式名称就是《ECMAScript 2015标准》(简称 ES2015)。2016年6月,小幅修订的《ECMAScript 2016标准》(简称 ES2016)如期发布,这个版本可以看作是 ES6.1 版,因为两者的差异非常小,基本上是同一个标准。根据计划,2017年6月发布 ES2017 标准。因此,ES6 既是一个历史名词,也是一个泛指,含义是5.1版以后的 JavaScript 的下一代标准,涵盖了ES2015、ES2016、ES2017等等,而ES2015 则是正式名称,特指该年发布的正式版本的语言标准。

letconst

变量提升

在ES6之前,JavaScript的作用域只有两种:全局作用域和函数作用域。而在这两个作用域里,存在一种奇怪的现象--变量提升。MDN上的介绍是 在编译阶段将变量和函数声明放入内存中,但仍然保留在编码中键入的位置。


    function(){
        console.LOG(a);
        VAR a= 'hello';
    }


    function(){
        var a = undefined;
        console.log(a);
        a= 'hello';
    }

上面的两段代码是等价的,也说明了变量提升的本质。在函数作用域内,函数或者变量的声明会被放到作用域顶部,而其他操作仍然保留在原来的键入位置。

块级作用域

ES6中引入块级作用域的概念,和Java或者c语言中的局部变量作用域很像。因此,ES6中的块级作用域存在以下特点:暂时性死区、不可重复命名、不存在变量提升。通过关键字letconst声明的变量只在块级作用域内有效。


    {
        let i = 1;
    }
    console.log(i);//Error

上面的代码块解释了ES6中的块级作用域的概念,一个{}即为一个块级作用域,作用域内的变量在作用域外无法被访问。

暂时性死区

块级作用域首先带来的问题就是暂时性死区。从作用域开始到变量被声明之前的空间内是该变量的死区,在这个空间内不能对该变量进行任何操作。例如:


    {
        //死区开始
        i = 2;//Error
        console.log(i);//Error            
        let i = 1;//死区结束
    }

不可重复命名

这个很容易理解,var声明的变量可以重复命名,后来的命名可以把之前的覆盖掉,但是let声明的变量如果出现重复命名的情况,会直接报错。

const

const用来声明常量,一旦声明,值就不可改变。因此,const一旦声明,就必须立即初始化。这一点和Java或者C语言很像。

但是对于复合型变量,变量名不是指向数据,而是指向数据所在的地址。因此,const定义的复合型变量,只能保证变量名指向的地址不变,并不能确保改地址的内存储的数据不变。


    const foo = {};
    foo.a = 1;

    foo = {}//Error

    const b = [];
    b.length = 1;
    b = [];//Error

上面的一段代码中,分别用const声明了一个对象和一个数组。我们可以给对象或者数组的一个属性赋值,但是不能直接给对象或者数组整体赋值。

变量的解构赋值

数组的解构赋值

结构赋值是ES6引入的一种新的变量赋值方式, MDN上的解释是:解构赋值语法是一个Javascript表达式,这使得可以将值从数组或属性从对象提取到不同的变量中。


    let [a, b, c] = [1, 2, 3];
    console.log(a,b,c);//1 2 3

    let [foo, [[bar], baz]] = [1, [[2], 3]];
    console.log(foo, bar, baz);//1 2 3

上面的代码是两种数组解构赋值,只要等号左边的变量在右边的数组中能够找到对应的位置,就可以进行解构赋值。

对象的解构赋值

对象的结构赋值和数组略有不同。let { key:name } = obj。等价于 let name = obj[key]。

let obj = { First: 'hello', second: 'world' };
let { first: f, second: s } = obj;
console.log(f, s);//hello world
console.log(first, second);//Error

let { foo, bar } = { foo: "aaa", bar: "bbb" };
console.log(foo, bar);// aaa bbb

let { bar, foo } = { foo: "aaa", bar: "bbb" };
console.log(foo, bar);// aaa bbb

后两段代码是对象属性名和值相同时的简洁写法。从后两段代码我们可以了解对象解构赋值的本质:先在对象内部找到和变量名相同的属性,然后再把属性值赋给变量。对象的解构赋值本身是一次变量赋值运算

解构赋值也可以设置默认值,当结构失败时,直接取默认值。例如:


    var {x = 3} = {};
    console.log(x); //3

    var {x, y = 5} = {x: 1};
    console.log(x, y) // 1 5

解构赋值的用处

  • 用作变量交换。 [x, y] = [y, x];
  • 函数返回多个值。 [x, y] = func();
  • 对象的快速赋值。 let a={x:1,y:2,z:3,w:4}; let {x,y}=a; let b={x,y};
  • 导入模块的部分功能。 import {getOS} From '../utils';
  • 函数的解构参数(函数的扩展里详解)

函数的扩展

函数参数默认值

ES6中为函数加入了添加默认值的功能。


    function log(x, y = 'World') {
    console.log(x, y);
    }

    log('Hello');//Hello World

下边的代码有点意思,是函数解构参数的默认值写法。


    // 写法一
    function m1({x = 0, y = 0} = {}) {
        return [x, y];
    }

    // 写法二
    function m2({x, y} = { x: 0, y: 0 }) {
        return [x, y];
    }


    m1({x: 3});
    m2({x: 3});

两种写法略有不同,所表达的意思也不一样。首先,函数的解构参数的写法是这样的:


    function add({x, y}){
        return x + y;
    }

当然,这里也可以是数组解构,上面的代码拿对象解构做事例。

写法一,两个大括号相等,表达的意思是函数参数拥有默认值,当m1函数被调用时没有传递参数时,区默认值即{}。之后,进行解构赋值。方法一里的解构赋值是带有默认值的解构赋值,因此,当解构失败时,x和y分别取默认值0。所以m1({x: 3})的执行结果是[3,0]。

写法二,两个大括号相等,同样表达的意思是函数参数拥有默认值,当m2函数被调用时没有传递参数时,区默认值即{ x: 0, y: 0}。方法二里的解构赋值没有默认值,因此,当解构失败时,x和y的值都是undefined。所以,m2()的值是[0,0],但是m2({x: 3})的则是[3,undefined]。

函数的解构参数最大的意义在于,我可以不用关心传递过来的数组或者对象内部的解构,只要内部有我想要的属性值就够了,这样在一定程度上降低了逻辑函数之间的耦合。例如:

let obj = {
    name: 'hello',
    age: 18,
    address: 'BeiJing',
    mobile: '123123123',
    timestamp: '1496940548319'
}

function getName({name}){
    return name;
}

getName(obj);



rest参数

ES6为函数参数引入rest写法。也就是我们偶尔会在ES6代码里见到的 ...


    function add(...values) {
        let sum = 0;

        for (let val of values) {
            sum += val;
        }

        return sum;
    }

rest参数用于获取函数的多余参数,类似于arguments对象。与之不同的是,rest参数是一个数组,也就意味着我们可以对rest参数使用数组的所有方法。

箭头函数

ES6的函数扩展里,最引人注意的应该就是箭头函数了。一个最简单的箭头函数:let f = v => v 等价于


    let f = function(v){
        return v
    }

当箭头函数没有参数或者有多个参数时,使用括号把参数括起来。当箭头函数的函数体多于一行代码时,就采用花括号把函数体括起来,并使用return语句返回值。

箭头函数的出现,主要是为了简化函数的书写。对于开发而言,最大的好处是简单易读,同时匿名函数写起来也更加舒服自然。

结语

ES6的基本扩展还有一些没有在这里详细介绍。总体感觉,ES6做了一些语法的丰富,使得JavaScript写起来更加舒服了,特别是结构赋值和箭头函数的引入,用习惯了以后,完全是另外一种编程体验。

脚本宝典总结

以上是脚本宝典为你收集整理的ES6学习手稿之基本类型扩展全部内容,希望文章能够帮你解决ES6学习手稿之基本类型扩展所遇到的问题。

如果觉得脚本宝典网站内容还不错,欢迎将脚本宝典推荐好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。