ES6核心学习(一)

1.块级作用域变量

   使用let/const,而非var来声明变量。

   var的问题是变量会泄漏到其它代码块,比如for循环或是if块。

2.立即执行函数表达式(IIFE)

1 //ES5 
2 3 
4       var private = 1;
5 
6 7    console.log(private);//1

  private会发生泄漏。需要使用立即执行函数表达式将其包起来

 

1 ES5
2 (function(){
3    var private2=1;
4 })();
5 console.log(private2);// Uncaught ReferenceError

  如果看过jquery或是其它开源项目的代码,你会注意到它们都利用了立即执行函数表达式,以避免污染全局环境,而只在全局下定义_\$或是jQuery。

  ES6更工整,不再需要使用IIFE,只用块和let就可以了:

1 //ES6
2 {
3    let private3 = 1;
4 }
5 console.log(private3);//Uncaught ReferenceError

3.Const

   如果不希望变量的值再改变,可以使用const。

4.类和对象

  在javascript中,每个对象都有原型对象。所有javascript对象都从原型上继承方法和属性。

  ES5以面向对象编程的方式创建对象,是利用构造函数实现的:

  

 1 //ES5
 2 var Animal = (function(){
 3   function MyConstructor(name){
 4      this.name = name;
 5  }
 6   MyConstructor.prototype.speak = function speak(){
 7       console.log(this.name+' makes a noise'.);
 8  }
 9   return MyConstructor;
10 })();
11   var animal = new Animal('animal);
12    animal.speak();//animal makes a noise.

 ES6提供了语法糖,可以用class、constructor等新的关键字、更少的样板代码实现相同的效果。

 

 1 ES6
 2 class Animal{
 3    constructor(name){
 4      this.name = name;
 5   }
 6    speak(){
 7      console.log(this.name +'makes a noises.');
 8   }
 9 }
10 const animal = new Animal('animal');
11  animal.speak();//animal makes a noise.

最佳实践:

    最好使用class语法,避免直接操作prototype。原因是这样代码更简明易懂。

   避免出现空的构造器,如果没有指明,类会有默认的构造器。

5.继承

  ES5

 1 //传统构造函数继承
 2 function Animal() {
 3     this.eat = function () {
 4         alert('Animal eat')
 5     }
 6 }
 7 function Dog() {
 8     this.bark = function () {
 9         alert('Dog bark')
10     }
11 }
12 Dog.prototype = new Animal()// 绑定原型,实现继承
13 var hashiqi = new Dog()
14 hashiqi.bark()//Dog bark
15 hashiqi.eat()//Animal eat

ES6提供了新的关键字extends和super

 1 //ES6继承
 2 class Animal {
 3     constructor(name) {
 4         this.name = name
 5     }
 6     eat() {
 7         alert(this.name + ' eat')
 8     }
 9 }
10 class Dog extends Animal {
11     constructor(name) {
12         super(name) // 有extend就必须要有super,它代表父类的构造函数,即Animal中的constructor
13         this.name = name
14     }
15     say() {
16         alert(this.name + ' say')
17     }
18 }
19 const dog = new Dog('哈士奇')
20 dog.say()//哈士奇 say
21 dog.eat()//哈士奇 eat

效果相同,但是相比于ES5,ES6代码更易读,完胜。

6.Promise

  Promise是异步编程的一种解决方案,比传统的解决方案(回调函数和事件)更合理更强大

 1 function printAfterTimeout(string, timeout, done){
 2   setTimeout(function(){
 3     done(string);
 4   }, timeout);
 5 }
 6 printAfterTimeout('Hello ', 2e3, function(result){
 7   console.log(result);
 8   // nested callback
 9   printAfterTimeout(result + 'Reader', 2e3, function(result){
10     console.log(result);
11   });
12 });

 这个函数接收一个回调,在done后执行。我们想要先后执行两次,所以在回调中又一次调用了printAfterTimeout。如果需要3或4次回调,代码很快就一团糟了。

ES6中的promise很好的解决了回调地狱的问题,所谓的回调地狱是指当太多的异步步骤需要一步一步执行,或者一个函数里有太多的异步操作,这时候就会产生大量嵌套的回调,使代码嵌套太深而难以阅读和维护。ES6认识到了这点问题,现在promise的使用,完美解决了这个问题。

promise 原理:

promise对象初始化状态为pending:当调用resolve(成功),会由pending=>fulfilled;

当调用reject(失败),会由pending=>rejected,具体流程见下图:

promise的使用流程

1.new Promise一个实例,而且要return

2.new Promise时要传入函数,函数有resolve reject两个参数

3.成功时执行resolve,失败时执行reject

4.then监听结果

 1 function loadImg(src){
 2    const promise=new Promise(function(resolve,reject){
 3      var img=document.createElement('img' 4      img.onload=function(){
 5         resolve(img)
 6    }
 7      img.onerror=function(){
 8         reject()
 9    }
10     img.src=src
11  })
12   return promise//返回一个promise实例
13 }
14 var src="http://www.imooc.com/static/img/index/logo_new.png"
15 var result=loadImg(src)
16 result.then(function(img){
17     console.log(img.width)//resolved(成功)时候的回调函数
18 },function(){
19     console.log(“failed“)//rejected(失败)时候的回调函数
20 })
21 result.then(function(img){
22     console.log(img.height)
23 })

promise 中可以用 then 在某个函数完成后执行新的代码,而不必再嵌套函数。

7.ES6模块化

  ES6实现了模块功能,旨在成为浏览器和服务器通用的模块解决方案。其模块功能主要由两个命令构成:export和

  import。export命令用于规定模块的对外接口,import命令用于输入其它模块提供的功能。

 

 1 /** 定义模块 math.js **/
 2 var basicNum = 0;
 3 var add = function (a, b) {
 4     return a + b;
 5 };
 6 export { basicNum, add };
 7 /** 引用模块 **/
 8 import { basicNum, add } from './math';
 9 function test(ele) {
10     ele.textContent = add(99 + basicNum);
11 }

 

如上例所示,使用import命令的时候,用户需要知道所要加载的变量名或函数名,否则无法加载。为了给用户

提供方便,让他们不用阅读文档就能加载模块,就要用到export default命令,为模块制定默认输出。

1 export default function(){
2    console.log('foo);
3 }

上面代码是一个模块文件export-default.js,它的默认输出是一个函数。其它模块加载该模块时,import命令可以为

该匿名函数指定任意名字。

1 import customName from './export-default';
2 customName();//'foo'

 

上面代码的import命令,可以用任意名称指向export-default.js输出的方法,这时就不需要知道原模块输出的函数

名。需要注意的是,这时import命令后面,不使用大括号。

 

posted @ 2019-05-31 16:37  伊娜陈  阅读(155)  评论(0编辑  收藏  举报