06月15, 2016

ES6的那些坑

我们在平常写ES6代码时,需要注意的点有哪些呢?

1.const常量定义

const a = 1;
a = 2;

这样是不对的,但是如下就没有问题

const obj = { "name":  "lilei"};
obj.name = "zp";

2.对象的解构赋值语法

var {key1, key2} = {"a": 1, "b": 2};
console.log(key1, key2);

不要奇怪结果是undefined, undefined。因为对象是无序的,所以必须要写对应的key值才行。

var {a1, a2} = {"a": 1, "b": 2};
console.log(a1, a2);

补充于2016年7月11日

可以通过以下的方式来改写:

var person = {
    name:"zfpx",
    age:6
}

let {name:a,age:b} = person;
console.log(a,b);

3.for of

var obj = {"a": 1, "b": 2};
for (var i of obj){
    console.log(i);
}

报错,是因为for of只能遍历有迭代器接口的,比如说数组,字符串,而对象没有。

那么问题来了,怎么给对象添加一个迭代器接口。

for-of 循环在集合中先调用 Symbol.iterator 方法。然后返回一个新的迭代器对象。一个迭代器对象可以是任意包含 .next() 方法的对象;for-of 会在循环的过程中重复调用这个方法。

最简单的迭代器对象:

var objIterator = {
  [Symbol.iterator]: function () {
    return this;
  },
  next: function () {
    return {done: false, value: 0};
  }
};

给所有的对象添加迭代器接口:

Object.prototype[Symbol.iterator] = function(){
    var _this = this,
        keys = Object.keys(_this),
        index = 0;
    return {
        next(){
            if(index < keys.length){
                return {
                    value: _this[keys[index++]],
                    done: false
                }
            }else{
                return {
                    value: undefined,
                    done: true
                }
            }
        }
    }
}

那么它就可以通过for of,来打印得到对象的value值。

4.Object.is方法判断NaN是否相同

Object.is(NaN, NaN);

结果为true,它帮忙解决了

NaN === NaN

返回false的问题

5.Object.assign

var arr = Object.assign([], ["1"], ["2"]);
console.log(arr);

期望得到的值为[1,2],可最终结果是[2]。我的理解是,它里面处理的方式,和对象相同,数组的key为索引,因为两个数据的长度相同,然后后者把前者相同的索引的value给覆盖了。

var arr = Object.assign([], [1,3], [2]);
console.log(arr)

按照上面的理解,得到的结果应该是2,3。运行之后,确实是。

6.Proxy

var obj = {"a": 1, "b": 2};

var p1 = new Proxy(obj, {
  get(obj, attr){
    return obj[attr];
  },
  set(obj, attr, value){
      obj[attr] = value;
  }
});

p1.a = 10;

console.log(p1.a);

上面的代码理论上是没问题的,但却执行不了最后一行的console,原因是在于目前的Proxy的set方法里面必须return一个结果出来,即:

new Proxy({
    get(obj, attr){
        return obj[attr];
    },
    set(obj, attr, val){
        //省略一些操作
        return 1; //具体返回什么值不是太重要,重要的是return回去一个结果
    }
})

7.数组的Object.observe

var arr = [1, 2, 3];

Object.observe(arr, function(obj){
    console.log("观察数组的改变")
    console.dir(obj);
})

arr.push(7);

本以为obj数组只有一个对象,就是add。打印出来的结果大吃一惊:

array-observe

从结果反推,我的猜测是,先把数据的最后一个元素给复制地加过去,然后再把最后一个元素给update掉。

关于Object.observe更多的资料,大家可以参考这篇文章,写的蛮详细的。

8.函数的不定参数

function test(...rest, d){
    console.log(rest);
}

test(1, 2, 4, 5);

本意是想快速地拿到最后一个参数,但是这样的写法,语法不支持,可以改成如下写法:

function test(...rest){
    console.log(rest[rest.length-1]);
}

test(1, 2, 4, 5);

9.箭头函数

var Person = () => {
    this.name = "aaa";
}

var p = new Person();

在node下运行的结果如图:

运行结果

what's the fuck!

OK,这里需要注意两点:

a.函数体内的this对象,是绑定定义时所在的对象,而不是使用时所在的对象。

b.不可以当做构造函数,不可以使用new命令

同时,箭头函数体内不存在arguments对象。

10. Class extends

如果子对象,和父对象都有构建函数,并且子对象在父对象的基础上增加了一些参数,则必须要显示调用super方法

class Person{
    constructor(name="zp"){
        this.name = name;
    }
    showName(){
        return this.name;
    }
}

class Son extends Person{
    constructor(age, name){
        this.age = age;
    }
}

var son = new Son("18");
console.log(son.showName());

运行时,会出错。如图所示

没加super的结果

根据提示,我们只需要改成这样即可

class Son extends Person{
    constructor(age, name){
        super(name);
        this.age = age;
    }
}

11. export 和 import的一些坑

var name 1 = "abc";
function test(){
    console.log("111");
}

export name1;
export test;

以上写法,会报错。

要么用default,要么用对象形式导出。

export deault name1;

//or export object
export {name1}

More on importing and exporting

    // Default exports and named exports
    import theDefault, { named1, named2 } from "src/mylib";
    import theDefault from "src/mylib";
    import { named1, named2 } from "src/mylib";

    // Renaming: import named1 as myNamed1
    import { named1 as myNamed1, named2 } from "src/mylib";

    // Importing the module as an object
    // (with one property per named export)
    import * as mylib from "src/mylib";

    // Only load the module, don’t import anything
    import "src/mylib";
    export var myVar1 = ...;
    export let myVar2 = ...;
    export const MY_CONST = ...;

    export function myFunc() {
        ...
    }
    export function* myGeneratorFunc() {
        ...
    }
    export class MyClass {
        ...
    }

参考资料

本文链接:www.my-fe.pub/post/es6-attention.html

-- EOF --

Comments

评论加载中...

注:如果长时间无法加载,请针对 disq.us | disquscdn.com | disqus.com 启用代理。