欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

ES6语法的新特性

程序员文章站 2024-03-18 10:33:58
...

之前面试被问到ES6新特性,箭头函数,generator、Module等等,表示刚开始上手用ES6,目前还没有很深入,所以这次想对ES6一些常用的特性进行整理。

let和const

主要是实现块级作用域的。因为在原生JS中,没有块级作用域。只有在函数中,才构成一个作用域,但是利用函数是可以实现一个类似于块级作用域的。详见这里

不过,为了更方便的解决类似于下面这种问题:

setTimeout(function(){
    for( var i = 0; i < 10; i++)
    {
        console.log(i);
    }
})

ES6引入了两个新的特性,letconst

letvar有什么区别呢?

1. `let`声明的变量有块级作用域,不能作为全局对象的全局属性被访问,即不能通过window来访问;
2. `let` 声明的变量不能被重复声明,而`var`没有关系;
3. 像 `for(let i ......)`这种形式,会在每次迭代对`i`进行绑定。

const与let类似,唯一的不同就在于const声明变量时必须初始化,并且初始化之后就不能再对值进行修改了,否则会报错!

箭头函数

箭头函数出现的目的是为了让JS代码显得更简洁一些。

// 六种语言中的简单函数示例
    function (a) { return a > 0; } // JS
    [](int a) { return a > 0; }  // C++
    (lambda (a) (> a 0))  ;; Lisp
    lambda a: a > 0  # Python
    a => a > 0  // C#
    a -> a > 0  // Java

我们都知道函数式编程很普遍,而且原生JS来实现比较冗长,所以ES6新引入了一种箭头函数的写法。

那么箭头函数和普通函数有什么区别呢?主要区别就是this的指向。在箭头函数里面是没有自己的this的,里面的this继承自外围作用域。而普通函数是有自己的作用域的,所以才会在引入闭包的时候,this一般都指向全局window对象。

var obj = {
    name: 'heihei',
    sayName: function(){
        return function(){
            console.log(this);
        }
    }
}

var obj1 = {
    name: 'Hellen',
    sayName: function(){
        return ()=>{ console.log(this) };
    }
}

ES6语法的新特性

另一点不同,就是箭头函数里面是访问不到arguments参数列表的,所以只能通过不定参数和默认参数这两个机制来实现。可参考这篇文章

class类

在原生ES5中,我们通常利用构造函数来创建对象,而ES6引入一种与Java,C++等更接近的方法来创建对象-class。

我们对比下构造函数和class有什么不同。

 function Circle( radius ) {
     this.radius = radius;
     this.area = function(){
        return Math.pow(this.radius, 2) * Math.PI;
    }
 }

var c = new Circle(4);
var area = c.area();
console.log(area);
class Circle {
    constructor( radius ) {
        this.radius = radius;
    };
    area() {
        return Math.pow(this.radius, 2) * Math.PI;
    }
}

var c = new Circle(4);
var area = c.area();
console.log(area);

在写法上,除了类的定义与构造函数不同,在用法上是相同的语法。不同的地方我们看下下面两张图就明白了。
这是利用构造函数构造的对象:
ES6语法的新特性

利用Class创建的对象:
ES6语法的新特性

Iterator(遍历器)

在原生JS中,遍历对象/数组有这么几种方式:

  • for循环
//最简单也最直观的循环遍历
var arr = [2,6,5];
for(var i = 0; i < arr; i++) {
    console.log(arr[i]);
}
  • forEach
//写法比上面的简单很多;
//但是对于对象不使用,并且不能跳出循环,即用break,continue,return等
var arr = [2,6,5];
arr.forEach(function(data) {
    console.log(data);
})
  • for … in
//对于数组而言,是按照arr['0'],arr['1']来访问的;
//不一定按顺序访问的
//专门适用于对象的遍历
var arr = [2,6,5];
for(var index in arr) {
    console.log(arr[index]);
}

Iterator的出现就是为解决上面的一些缺点出现的,为的是给不同的数据结构产生统一的接口。只要部署一个Iterator接口,就可以为for ... of 服务,从而实现遍历。

Iterator的过程是这样的:

  1. 创建一个指针对象,指向数据结构的起始位置;
  2. 调用指针对象的next方法,指针指向数据结构的第一个成员;
  3. 一次类推,直到返回数据结构的最后一个成员。

    Iteratornext方法返回的是一个对象:{ value: 成员对象的值, done:false/true }

其实在数组、字符串,以及ES6的Map和Set中,都有默认的Iterator接口,因为有遍历器接口,所以才能调for ... of来实现遍历。那我们看看默认的Iterator接口是什么样的?
ES6语法的新特性
上图是一个数组对象的原型链上的方法。其中有一个Symbol.iterator函数,这个函数其实就是一个遍历器接口。我们来使用一下:

ES6语法的新特性

这个函数返回的是一个对象表示数组Iterator。并且在这个对象里有next方法,这跟我们前面说的是相吻合的。
ES6语法的新特性

每一次调用next方法之后,就会返回一个对象,value表示数据结构当前位置的数值,done表示是否到最后一个成员。

所以只要一个数据结构,有这个接口,都可以调用for…of方法来实现。
ES6语法的新特性
ES6语法的新特性

因为Object里面没有Iterator接口,所以不能直接用for…of实现遍历,那怎么办呢?
其实可以先调Object.keys将对象转成数组。
ES6语法的新特性

后期还会续上generator生成器对象(迭代器对象)以及modules等新特性。