资讯专栏INFORMATION COLUMN

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

tommego / 1804人阅读

摘要:它是一个通用标准,奠定了的基本语法。年月发布了的第一个版本,正式名称就是标准简称。结语的基本扩展还有一些没有在这里详细介绍。

前言

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 则是正式名称,特指该年发布的正式版本的语言标准。

let和const 变量提升

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

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


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

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

块级作用域

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

    {
        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写起来更加舒服了,特别是结构赋值和箭头函数的引入,用习惯了以后,完全是另外一种编程体验。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/90445.html

相关文章

  • React手稿 React-Saga

    摘要:相当于一个放置在与中的垫片。之所以称之谓副作用呢,就是为了不让触发一个时,立即执行。也就是在与之间做一个事情,比如异步获取数据等。使用了中的功能,避免了像的回调地狱。把放入中最后再实现相就的即可在线示例推荐阅读手稿 Redux-Saga redux-saga 是一个用于管理应用程序副作用(例如异步获取数据,访问浏览器缓存等)的javascript库,它的目标是让副作用管理更容易,执行更...

    notebin 评论0 收藏0
  • React手稿 React-Redux

    摘要:属性是必须的。需要一个与的一致。必须在的返回原。调试插件日志安装组件。然后加入到中即可例如扩展程序需要在应用市场安装然后在中使用增强功能将加入即可在线实例推荐阅读手稿 React-Redux Redux Action function addTodo(text) { return { type: ADD_TODO, text } } type 属性是必须的。...

    Freelander 评论0 收藏0
  • React手稿类型检查

    摘要:类型检查是为了确保传入组件的参数正确性。通常在项目中可以使用或者来实现。示例以上内容在实现一个通用组件时非常有用。类型检查和参数默认值一起使用,保证组件的正常运行。 Typechecking With PropTypes 类型检查是为了确保传入组件的参数正确性。 通常在项目中可以使用Flow或者TypeScript来实现。 React提供了PropTypes来检查类型。 示例: imp...

    tomorrowwu 评论0 收藏0
  • React手稿State Hooks of Hooks

    摘要:官方也陈述,接下来的的工作会投入到中。从目前官方的文档可以看出,从以下四个方面来提高的编码。生命周期自定义方法的主要用途是替代之前版本的组件。说明到目前为止,在已发布的版本中有该功能,想体验该功能,必须安装。 React Hooks React在16.7.0-alpha.0版本中提到了Hooks的概念,目前还是Proposal阶段。 官方也陈述,接下来的90%的工作会投入到React ...

    DC_er 评论0 收藏0
  • Memcache/Memcached的PHP操作手册(纯手稿版)

    摘要:和其实是一个东西,只是中要是用的扩展不一样年左右有人丰富的用法和性能,编写了一个是独立第三方,才有了用法也有了很大的改进比如添加了批量获取键值下只能安装扩展并不存在所以中只能使用不能使用类打开一个到服务器的持久化连接连接不会在脚本执行结 Memcache和Memcached 其实是一个东西,只是php中要是用的扩展不一样, 2009年左右有人丰富memcache的用法和性能,编写了一个...

    BlackHole1 评论0 收藏0

发表评论

0条评论

tommego

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<