前端进击之路——初识ES6

 

  • 变量声明let和const
  • 模板字符串
  • 箭头函数
  • 解构赋值
  • 展开运算符
  • 模块化import和export
  • Promise

 

1.变量声明let和const

我们通常用 `let`和 `const`来声明, `let`表示变量、`const` 表示常量。 `let` 和 `const`都是块级作用域。块级作用域可以理解为在{}大括号内的代码块。

let 定义的变量不会被变量提升;let的作用域是在它所在当前代码块,不会被提升到当前函数的最顶部。

  function ha() {
    if(flag) {
       let test = 'hello Doraemon~';
    } else {
        //test is not defined
        console.log(test)
    }
  }

再来说说const ,const 定义的常量不能被修改,const定义的对象所指向的地址不能改变,对象的属性值可以改变(改变指针指向就会报错。因为对象是引用类型的,P中保存的仅是对象的指针,这就意味着,const仅保证指针不发生改变,修改对象的属性不会改变对象的指针,所以是被允许的。也就是说const定义的引用类型只要指针不发生改变,其他的不论如何改变都是允许的。

TDZ(暂时性死区) 

我们都知道,JS引擎扫描代码时,如果发现变量声明,用 var 声明变量时会将声明提升到函数或全局作用域的顶部。但是使用 `let` 或者 `const`,会将声明关进一个小黑屋也是TDZ(暂时性死区),只有执行到变量声明这句语句时,变量才会从小黑屋被放出来,才能安全使用这个变量。

console.log(a);  // undefined
var a = 'hello';

// 上面的代码相当于
var a;
console.log(a);
a = 'hello';

//而 let 就不会被变量提升
console.log(a); // a is not defined
let a = 'hello';

2.模板字符串

模板字符串解决了 ES5 在字符串功能上的痛点。

第一个用途:字符串拼接。将表达式嵌入字符串中进行拼接,用 反引号 ` 和 ${}` 来界定。

    //ES5 
    var name = 'King'
    console.log('hello' + name)

    //es6
    const name = 'King'
    console.log(`hello ${name}`) //hello King
    

第二个用途,在ES5时我们通过反斜杠(\)来做多行字符串或者字符串一行行拼接。ES6反引号(``)直接搞定。

// es5
var msg = "Hi \
man!";

// es6
const name = 'Lys', age = 23;
const template = `

${name}

${age}

`;

3.箭头函数

箭头函数最直观的三个特点。()=>{} 

  • 不需要 function 关键字来创建函数
  • 省略 return 关键字
  • 继承当前上下文的 this 关键字,箭头函数没有自己的this,它的this是继承而来,默认指向在定义它时所处的对象,而不是执行时的对象。
// ES5
var arr1 = [1, 2, 3];
var newArr1 = arr1.map(function(x) {
  return x + 1;
});

// ES6
let arr2 = [1, 2, 3];
let newArr2 = arr2.map((x) => {
  x + 1
});

 箭头函数小细节:当你的函数有且仅有一个参数的时候,是可以省略掉括号的;当你函数中有且仅有一个表达式的时候可以省略{}

let arr2 = [1, 2, 3];
let newArr2 = arr2.map(x => x + 1);

 JavaScript语言的this对象一直是一个令人头痛的问题,运行上面的代码会报错,这是因为setTimeout中的this指向的是全局对象。

class Animal {
    constructor() {
        this.type = 'animal';
    }
    says(say) {
        setTimeout(function() {
            console.log(this.type + ' says ' + say);
        }, 1000);
    }
}

var animal = new Animal();
animal.says('hi'); //undefined says hi

 解决办法:

// 传统方法1: 将this传给self,再用self来指代this
says(say) {
    var self = this;
    setTimeout(function() {
        console.log(self.type + ' says ' + say);
    }, 1000);
}

// 传统方法2: 用bind(this),即
says(say) {
    setTimeout(function() {
        console.log(this.type + ' says ' + say);
    }.bind(this), 1000);
}

// ES6: 箭头函数
// 当我们使用箭头函数时,函数体内的this对象,就是定义时所在的对象
says(say) {
    setTimeout(() => {
        console.log(this.type + ' says ' + say);
    }, 1000);
}

注:箭头函数不可以当作构造函数,也就是说,不可以使用new命令,否则会抛出一个错误。

4.解构赋值

解构可以简化数组和对象中信息的提取。在ES6之前,我们需要一个一个获取对象信息;ES6后,解构能让我们从对象或者数组里取出数据存为变量,具体来看下面的代码:

// ES5
var people1 = {
  name: 'bai',
  age: 20,
  color: ['red', 'blue']
};

var myName = people1.name;
var myAge = people1.age;
var myColor = people1.color[0];
console.log(myName + '----' + myAge + '----' + myColor);

// ES6
let people2 = {
  name: 'ming',
  age: 20,
  color: ['red', 'blue']
}

let { name, age } = people2;
let [first, second] = people2.color;
console.log(`${name}----${age}----${first}`);//ming----20----red

5.Spread Operator (展开运算符)

rest arguments (rest参数)解决了 es5 复杂的 arguments 问题

function foo(x, y, ...rest) {
    return ((x + y) * rest.length);
}
foo(1, 2, 'hello', true, 7); // 9

第一个用途:组装数组

let color = ['red', 'yellow'];
let colorful = [...color, 'green', 'blue'];
console.log(colorful); // ["red", "yellow", "green", "blue"]

第二个用途:获取数组除了某几项的其他项

let num = [1, 3, 5, 7, 9];
let [first, second, ...rest] = num;
console.log(rest); // [5, 7, 9]

6.Promise

promise:就是一个对象,用来传递异步操作的消息;可以将异步操作以同步操作的流程表达出来;

缺点:无法取消promise,一旦新建它,就会立即执行;

promise对象有两个特点:

1:对象的状态不受外界影响;有三种状态:Pending(进行中),Resolved(以完成),Rejected(已失败)。

只有异步操作的结果可以决定当前的状态;

2:一旦状态改变,就不会再变;Promise对象的状态改变只有两种可能,从pending->resolved或者从pending->rejected;

就算改变已经发生了,你再对promise对象添加回调函数,也会立即得到这个结果;

基本用法:

promise对象是一个构造函数,接受一个函数作为参数;该函数的两个参数分别是resolve和reject。它们是两个函数,由JavaScript引擎提供;

resolve函数作用是:将promise对象的状态从“未完成”变为“成功”;在异步操作成功时调用,并将异步操作的结果作为参数传递出去;

reject函数作用是:将promise对象的状态从“未完成”变为“失败”;在异步操作失败时调用,并将异步操作报出的错误作为参数传递出去;

promise实例生成后,可以用then方法接收两个回调函数作为参数,第一个是对象状态变为resolved时调用,第二个是状态变为rejected时调用,不一定提供;

Promise.prototype.then():

then()方法返回的是一个新的promise实例,因此可以采用链式写法;

如果依次指定了两个回调函数,第一个回调函数完成之后,就会返回结果作为参数传入第二个回调函数;

Promise.prototype.catch():

catch()方法返回的是一个promise()对象,因此可以采用链式写法;

catch是then(null,rejection)的别名,用于指定发生错误时的回调函数;

promise对象的错误具有“冒泡”的性质,会一直向后传递,直到被捕获为止;

Promise.all():

用于将多个promise实例包装成一个新的promise实例;

接收一个数组作为参数;如果数组中存在不是promise实例的,会先调用Promise.resolve方法,将参数转化为promise实例;

var p = Promise.all([p1,p2,p3]);

p的状态是由p1,p2,p3决定

1:只有p1,p2,p3状态都变为resolved时,p才会是resolved;

2:只要p1,p2,p3有一个状态变为rejected,p就会是rejected;

Promise.race():

用于将多个promise实例包装成一个新的promise实例;

只要有一个实例率先改变状态,p的状态就跟着改变,那个率先改变promise实例的返回值就传递给p的回调函数;

Promise.resolve():

将现有对象转化为promise对象,返回promise实例的状态从一开始就是resolved,所以回调函数会立即执行;

Promise.reject():

该方法也会返回一个新的promise实例,状态为rejected;

var getJSON = function(url){
    var promise = new Promise(function(resolve,reject){
        var XHR = new XMLHttpRequest();
        XHR.open("get",url);
        XHR.onreadystatechange = handler;
        XHR.responseType = "json";
        XHR.setRequestHeader("Accept","application/json");
        XHR.send();
        function handler(){
            if(this.readyState !==4){
                return ;
         }
         if(this.status === 200){
                resolve(this.response);
         }else{
                reject(new Error(this.statusText));
         }
      }
   });
    return promise;
}
promise.then(function(value){
    //code
},function(value){
    //code
});
promise.catch(function(error){
    //code
});

 

 

 

 

 

 

你可能感兴趣的:(前端进击之路——初识ES6)