JavaScript ES6

目录

9.1 ES6介绍

9.1.1 为什么要学习ES新特性

9.1.2 为什么要单独学习ES6

9.2 let 、const 详解

9.2.1 let 变量

9.2.2 块级作用域

9.2.3 const 常量

9.3 解构赋值

9.3.1数组模型的解构赋值

9.3.2对象模型的解构赋值

9.4 模板字符串

9.4.1声明

9.4.2 应用

9.5 对象的扩展

9.5.1 简化对象写法

9.5.2方法的 name 属性

9.5.3 扩展运算符

9.6 函数的扩展

9.6.1 参数默认值

9.6.2 rest参数

9.6.3 严格模式

9.6.4 name属性

9.6.5 箭头函数

9.7 Symbol

9.7.1 Symbol介绍

9.7.2 Symbol 特点

9.8 Promise 对象

9.8.1 Promise状态

9.8.2 Promise基本用法

9.9 Iterator (迭代器)与 for...of 循环

9.10 Generator 函数


9.1 ES6介绍

概述

ES全称EcmaScript,是由Ecma国际通过ECMA-262(Ecma国际制定了很多标准,ECMA-262是其中一个)标准化的脚本程序设计语言,脚本语言的一种规范,而平时编写的JavaScript,是EcmaScript的一种实现,所以ES新特性其实是指JavaScript的新特性

ES6是EcmaScript第六版本,全称:ECMAScript 6.0。2015年出版新增了:模块化,面向对象语法,Promise、箭头函数、let、const、数组解构赋值等等。ECMAScript 6 目前基本成为业界标准,它的普及速度比 ES5 要快很多,主要原因是现代浏览器对 ES6 的支持相当迅速,尤其是 Chrome 和 Firefox 浏览器,已经支持 ES6 中绝大多数的特性。

9.1.1 为什么要学习ES新特性

1.语法简洁,功能丰富

2.框架内开发应用

3.前端开发职业要求

9.1.2 为什么要单独学习ES6

1.ES6版本变动最多,具有里程碑意义

2.ES6加入许多语法新特性,编程实现更加简单、高效

3.ES6是前端发展趋势,就业必备技能

4.3.微信小程序,uni-app等都是基于ES6的语法

9.2 let 、const 详解

9.2.1 let 变量

ES6新增了let变量,它的用法类似于var,但是所声明的变量,只在let命令所在的代码块内有效。

let 允许创建块级作用域,ES6 推荐在函数中使用 let 定义变量,而非 var

let变量声明

声明方式:

let a;

let b,c,d;

注意事项:let变量不能重复声明,防止变量重复命名导致变量污染

重复声明报错:

let 作用域

简述:let变量声明仅在同一代码块内可以读取,只做用于块级作用域

{
  let hello = 'ES6';
}
console.log(hello); //Error:hello is not defined. hello 未定义

let 不存在变量提升

简述:变量在未声明前不可以使用

console.log(song);
let song = '请出现吧' 
//Error: Cannot access 'song' before initialization. 不允许在声明前使用

9.2.2 块级作用域

块级作用域产生原因

ES5只包括全局作用域和函数作用域,但是在应用中一些内层变量因为变量提升而变成全局变量,使内层逻辑不符常理,因此ES6出现“块级作用域”这一方法解决其产生的问题。

var a = '外层变量';

function fn() {
  console.log(a);
  if (false) {
	var a = '内层变量';
  }
}

fn();//undefined

块级作用域的应用

let 变量没有变量提升,仅在当前代码块内作用,其特点很好的解决了这一问题。

let实际上为 JavaScript 新增了块级作用域:

let a = '外层变量';

function fn() {
  console.log(a);
  if (false) {
	let a = '内层变量';
  }
}

fn();//外层变量

9.2.3 const 常量

同样在块级作用域有效的另一个变量声明方式是 const,const的与let的特点基本相同,同样不存在变量提升,只能在声明后使用。

const 常量声明

声明方式:

const NAME = 'ES6常量';

注意事项:常量声明时就需要赋值且一般常量值需要大写

const 常量值无法修改

const NAME = 6;
NAME = 5;
console.log('NAME');//Error: Assignment to constant variable

对数组和对象元素的修改,不算对常量值的修改,并不会报错

 const ARR = ['sa', '56ty', 'assd']
 ARR.push('uiop')
 console.log(ARR);// 正常输出:["sa", "56ty", "assd", "uiop"]

const 常量作用域

简述:仅在同一代码块内可以读取,只做用于块级作用域

 {
    const LEARNING = '常量';
 }
console.log(LEARNING); //Error:LEARNING is not defined 

9.3 解构赋值

概述

ES6允许按照一定模式从数组和对象中提取值,并对变量进行赋值。

解构赋值,左右结构必须一样,使用左边定义的值,快速的取出数据中对应的数据值,而且定义和赋值必须放到一起,不然的话就会报错,取不出来数据值

9.3.1数组模型的解构赋值

将左边数组中的变量按照对应的位置,在右边进行赋值,只要两边模式相同,左边变量会被赋予右边对应的值

基础解构赋值过程:

let [a, b, c] = [1, 2, 3];
// a = 1
// b = 2
// c = 3

嵌套解构赋值:

let [a, [[b], c]] = [1, [[2], 3]];
// a = 1
// b = 2
// c = 3

忽略解构赋值:

let [a, , b] = [1, 2, 3];
// a = 1
// b = 3

不完全解构赋值:

let [a, b] = [1, 2, 3];
// a = 1
// b = 2

9.3.2对象模型的解构赋值

解构不仅可以用于数组,还可以用于对象。

基础解构赋值过程:

let { one, two } = { one: 'aaa', two: 'bbb' };
// one = 'aaa'
// two = 'bbb'
 
let { one : two } = { one : 'ddd' };
// two = 'ddd'

对象的解构与数组有一个重要的不同。数组的元素是按次序排列的,变量的取值由它的位置决定;而对象的属性没有次序,变量必须与属性同名,才能取到正确的值。

let { two , one, } = { one: 'aaa', two: 'bbb' };
// one = 'aaa'
// two = 'bbb'
 
let { tr } = { three : 'ddd' };
tw  // undefined

嵌套解构赋值

let a = {b: ['learn', {c: 'ES6'}] };
let {b: [d, { c }] } = a;
// d = 'learn'
// c = 'ES6'

忽略解构赋值:

let a = {b: ['learn', {c: 'ES6'}] };
let {b: [d, {  }] } = a;
// d = 'learn'

不完全解构赋值

let a = {b: [{c: 'ES6'}] };
let {b: [c, { d }] } = a;
// d = undefined
// c = 'ES6'

9.4 模板字符串

ES6引入新的声明字符串方式 `` '' ""(反引号、单引号、双引号)

9.4.1声明

let str = `这是一个字符串啊!`

9.4.2 应用

使内容中可以出现换行符

        let str = ` <ul>
                       <li>11</li>
                       <li>22</li>
                       <li>33</li>
                    </ul>`;

变量拼接

        let learn = 'ES6';
        let view = `${learn}里面的模板字符串学习`
        
        console.log(view); //ES6里面的模板字符串学习

9.5 对象的扩展

9.5.1 简化对象写法

ES6 允许在大括号内,直接写入变量和函数,作为对象的属性和方法 提高代码书写的简洁性

      let name = 'ES6';
        let change = function() {
            console.log('这是普通无省略的函数声明方式!')
        }

        const school = {
            name,
            change,
            learn() {
                console.log("快看变量引入方式和函数声明方式!!");
            }
        }
        console.log(school);

控制台输出:

9.5.2方法的 name 属性

函数的name属性,返回函数名。对象方法也是函数,因此也有name属性。

var person = {
  sayName() {
    console.log(this.name);
  },
  get firstName() {
    return "Nicholas";
  }
};

person.sayName.name   // "sayName"
person.firstName.name // "get firstName"

上面代码中,方法的name属性返回函数名(即方法名)。如果使用了取值函数,则会在方法名前加上get。如果是存值函数,方法名的前面会加上set。

9.5.3 扩展运算符

拓展运算符(...)用于取出参数对象所有可遍历属性然后拷贝到当前对象。

基本用法

let student = {name: "aa", age: 10};
let one = { ...student };
someone;  //{name: "aa", age: 10}

自定义的属性和拓展运算符对象里面属性的相同的时,自定义的属性在拓展运算符后面,则拓展运算符对象内部同名的属性将被覆盖掉:

let student= {name: "aa", age: 10};
let one = { ...student, name: "bb", age: 18};
one;  //{name: "bb", age: 18}

自定义的属性在拓展运算度前面,则变成设置新对象默认属性值。

let student= {name: "aa", age: 10};
let one = { name: "bb", age: 18, ...student };
one;  //{name: "aa", age: 10}

扩展运算符应用于数组

数组的合并

   const a =['aaa','bbb','ccc'];
        const b =['ddd','eee','fff'];
        const c = [...a,...b];//['aaa','bbb','ccc','ddd','eee','fff']

数组的克隆

        const d = ['G','H','I']
        const e = [...d] 
        console.log(e) //['G','H','I']

将伪数组转为真正的数组

        const divs = document.querySelectorAll('div');
        const divArr = [...divs];
        console.log(e); //[div,div,div]

9.6 函数的扩展

9.6.1 参数默认值

在 ES6 之前,我们不能直接为函数的参数指定默认值,只能采用变通的方法。而 ES6 中允许我们直接为函数的参数设置默认值,通过等号 = 直接在小括号中给参数赋值

function fn(name,age="10")
{
	console.log(`我是${name},今年${age}岁`);
}
fn("小E"); //我是小E,今年10岁
传递undefined,取默认值:

function fn(name="小s",age)
{
	console.log(`我是${name},今年${age}岁`);
}
fn(undefined,15); //我是小s,今年15岁

9.6.2 rest参数

ES6引入rest参数(形式为“...变量名”),用于获取函数的多余参数,这样就不需要使用arguments对象了。rest参数搭配的变量是一个数组,该变量将多余的参数放入数组中。

rest 参数必须要放到参数最后, rest后面的参数没有意义

  function data(){
            console.log(arguments);//输出格式为对象
        }
        data('11','22','33');

        // rest参数
        function data(...args){
            console.log(args);//输出格式为数组,便于处理数据 
        }
        data('11','22','33');

9.6.3 严格模式

从ES5开始,函数内部可以设定为严格模式。

function learn(a, b) {
  'use strict';
  // code
}

《ECMAScript 2016标准》做了一点修改,规定只要函数参数使用了默认值、解构赋值、或者扩展运算符,那么函数内部就不能显式设定为严格模式,否则会报错。

这样规定的原因是,函数内部的严格模式,同时适用于函数体代码和函数参数代码。但是,函数执行的时候,先执行函数参数代码,然后再执行函数体代码。这样就有一个不合理的地方,只有从函数体代码之中,才能知道参数代码是否应该以严格模式执行,但是参数代码却应该先于函数体代码执行。

// 报错
function a(value = 070) {
  'use strict';
  return value;
}

上面代码中,参数value的默认值是八进制数070,但是严格模式下不能用前缀0表示八进制,所以应该报错。但是实际上,JavaScript引擎会先成功执行value = 070,然后进入函数体内部,发现需要用严格模式执行,这时才会报错。

虽然可以先解析函数体代码,再执行参数代码,但是这样无疑就增加了复杂性。因此,标准索性禁止了这种用法,只要参数使用了默认值、解构赋值、或者扩展运算符,就不能显式指定严格模式。

两种方法可以规避这种限制。第一种是设定全局性的严格模式,这是合法的。第二种是把函数包在一个无参数的立即执行函数里面。

//1.第一种
'use strict';

function learn(a, b = a) {
  // code
}


//2.第二种
const learn= (function () {
  'use strict';
  return function(value = 42) {
    return value;
  };
}());

9.6.4 name属性

函数的name属性,返回该函数的函数名

function a() {}
a.name // "a"

ES6对这个属性的行为做出了一些修改。如果将一个匿名函数赋值给一个变量,ES5的name属性,会返回空字符串,而ES6的name属性会返回实际的函数名。

var a = function () {};

// ES5
func1.name // ""

// ES6
func1.name // "a"

如果将一个具名函数赋值给一个变量,则ES5和ES6的name属性都返回这个具名函数原本的名字。

const b = function a() {};

// ES5
bar.name // "a"

// ES6
bar.name // "a"

9.6.5 箭头函数

概述

简化定义函数语法

省略小括号,当形参有且只有一个

let a = b => b;

上面的箭头函数等同于:

let a = function(b) {
  return b;
};

如果箭头函数不需要参数或需要多个参数,就使用一个圆括号代表参数部分。

let a = () => 5;
// 等同于
let a = function () { return 5 };

let sum = (num1, num2) => num1 + num2;
// 等同于
let sum = function(num1, num2) {
  return num1 + num2;
};

如果箭头函数的代码块部分多于一条语句,就要使用大括号将它们括起来,并且使用return语句返回。

let sum = (num1, num2) => { return num1 + num2; }

由于大括号被解释为代码块,所以如果箭头函数直接返回一个对象,必须在对象外面加上括号。

let a = id => ({ id: id, name: "cc" });

this指向

this 是静态的 this 始终指向函数声明时所在的作用域下的this值

        function getName() {
            console.log(this.name);
        }
        let getName2 = () =>{
            console.log(this.name);
        }

        window.name = '设置window对象的name属性';
        const school = {
            name: "函数声明时所在函数作用域下的name属性"
        }

箭头函数不能作为构造函数去实例化对象

  let Person = (name, age) => {
            this.name = name;
            this.age = age;
        }
        let me = new Person('xiao',30);
        console.log(me);//Error:Person is not a constuctor //Person 不是一个构造函数

9.7 Symbol

9.7.1 Symbol介绍

ES6 引入了一种新的原始数据类型Symbol,表示独一无二的值.是javaScript语言的第七种数据类型,类似于字符串

9.7.2 Symbol 特点

1.值是唯一的,可以用来解决命名冲突的问题

2.不能与其他数据进行运算

3.使用Symbol定义的对象属性不能使用for...in循环遍历,但是可以使用Reflect.ownKeys来获取对象的键名

Symbol函数创建

值是唯一的,可以用来解决命名冲突的问题

 let a = Symbol();
    let a1 = Symbol('这是a1');
    let a2 = Symbol('这是a1');
    console.log(a1 === a2);//false

创建Symbol.for(Symbol函数对象创建)

无法与其他数据进行运算

      let b = Symbol.for;
      let b1 = Symbol.for('这是b')
      let b2 = Symbol.for('这是b')
      console.log(b1 === b2);//true

Symbol创建对象属性

向对象中添加方法 up down

   let game ={}

    // 声明一个对象 
    let methods = {
        up: Symbol(),
        down: Symbol()
    };
    // 第一种添加方式:
    game[methods.up] = function(){
        console.log("upup")
    }
    game[methods.down] = function(){
        console.log("downdown")
    }
    console.log(game);

    // 第二种添加方式:
    let learn = {
        name:"对象内添加方法",
        [Symbol('say')]: function(){
            console.log("讲出来");
        },
        [Symbol('read')]: function(){
            console.log("读出来");
        },
    }

9.8 Promise 对象

概述

Promise 是ES6引入的异步编程的新的解决方案。它由社区最早提出和实现,ES6 将其写进了语言标准,统一了用法,原生提供了Promise对象。Promise 对象是一个构造函数,用来封装异步操作并可以获取其成功或失败的的结果,可以解决回调地狱的问题

9.8.1 Promise状态

Promise 异步操作有三种状态:pending(进行中)、fulfilled(已成功)和 rejected(已失败)。除了异步操作的结果,任何其他操作都无法改变这个状态。

1.promise 对象初始化状态为 pending
2.当调用resolve(成功),会由pending => fulfilled
3.当调用reject(失败),会由pending => rejected

Promise 对象只有:从 pending 变为 fulfilled 和从 pending 变为 rejected 的状态改变。只要处于 fulfilled 和 rejected ,状态就不会再变了即 resolved(已定型)。

9.8.2 Promise基本用法

ES6规定,Promise对象是一个构造函数,用来生成Promise实例。

Promise构造函数接受一个函数作为参数,该函数的两个参数分别是resolve和reject。它们是两个函数,由 JavaScript 引擎提供,不用自己部署。

const promise = new Promise((resolve, reject) => {
       // 异步处理
       // 处理结束后、调用resolve 或 reject
});

resolve函数的作用是,将Promise对象的状态从“未完成”变为“成功”(即从 pending 变为 resolved),在异步操作成功时调用,并将异步操作的结果,作为参数传递出去;reject函数的作用是,将Promise对象的状态从“未完成”变为“失败”(即从 pending 变为 rejected),在异步操作失败时调用,并将异步操作报出的错误,作为参数传递出去

Promise实例生成以后,可以用then方法分别指定resolved状态和rejected状态的回调函数。

promise.then(function(value) {
  // success
}, function(error) {
  // failure
});

Promise.prototype.then()

Promise 实例具有then方法,也就是说,then方法是定义在原型对象Promise.prototype上的。它的作用是为 Promise 实例添加状态改变时的回调函数。它最多需要有两个参数:Promise 的成功和失败情况的回调函数。

const promise1 = new Promise((resolve, reject) => {
  resolve('Success!');
});

promise1.then((value) => {
  console.log(value);
  // expected output: "Success!"
});

Promise.prototype.catch()

catch() 方法返回一个promise,并且处理拒绝的情况。

p.catch(onRejected);

p.catch(function(reason) {
   // 拒绝
});

Promise.prototype.finally()

finally() 方法返回一个promise。在promise结束时,无论结果是fulfilled或者是rejected,都会执行指定的回调函数。这为在Promise是否成功完成后都需要执行的代码提供了一种方式。

p.finally(onFinally);

p.finally(function() {
   // 返回状态为(resolved 或 rejected)
});

9.9 Iterator (迭代器)与 for...of 循环

概述:
迭代器允许每次访问数据集合的一个元素,当指针指向数据集合最后一个元素时,迭代器便会退出。它提供了 next() 函数来遍历一个序列,这个方法返回一个包含 done 和 value 属性的对象。

ES6 中可以通过 Symbol.iterator 给对象设置默认的遍历器,无论什么时候对象需要被遍历,执行它的 @@iterator 方法便可以返回一个用于获取值的迭代器。

//声明一个数组
const web = ['h5','css','javaScript','jQuery','vue'];
//  使用for...of遍历数组, 展现的是数组的value值
for(let v of web){
  console.log(v);//h5 css javaScript jQuery vue
}
console.log(web);
//数组内有Symbol(Symbol.iterator): ƒ values() 函数,所以可以遍历

9.10 Generator 函数

Generator 函数是 ES6 的新特性,它允许一个函数返回的可遍历对象生成多个值。

在使用中你会看到 * 语法和一个新的关键词 yield:

function * learn(){
            yield '小白兔';
            yield '白又白';
            yield '两只耳朵';
            yield '竖起来';
        }

        // let iterator = learn();
        // console.log(iterator.next());//value: "小白兔" done: false
        // console.log(iterator.next());//value: "白又白" done: false
        // console.log(iterator.next());//value: "两只耳朵" done: false
        // console.log(iterator.next());//value: "竖起来" done: false

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值