ES6经常使用知识总结(20%的知识占80%的份额)

1、变量和常量

var的缺点:(1)var能够屡次声明同一个变量;   (2)var会形成变量提高 javascript

  1. (function rr() {  
  2.   if(true) {  
  3.     var a = 666;  
  4.   }  
  5.   console.log(a); //输出666  
  6. })()  

let以及const都是块级做用域。咱们经常使用let来声明一个值会被改变的变量,而使用const来声明一个值不会被改变的变量,也能够称之为常量。html

常见题:java

  1. for(var a = 0; a < 3; a++) {  
  2.   setTimeout(function() {  
  3.     console.log(a);  
  4.   }, 1000)  
  5. }  
  6. //输出结果都为3  

    如何将结果输出为0, 1, 2react

    es5处理方法 -- 用函数制造块级做用域es6

  1. for(var a = 0; a 3; a++) {  
  2.   (function (a) {  
  3.     setTimeout(function() {  
  4.       console.log(a);  
  5.     }, 1000)  
  6.   })(a)  
  7. }  
  8. //输出结果0,1,2  

    es6处理方法 -- 更加简单明了sql

  1. for(let a = 0; a < 3; a++) {  
  2.   setTimeout(function() {  
  3.     console.log(a);  
  4.   }, 1000)  
  5. }  
  6. //输出结果为:0,1,2  

2、解构赋值(Destructuring)

一、对象的解构赋值数组

const props = {
    className: 'tiger-button',
    loading: false,
    clicked: true,
    disabled: 'disabled'
}

当咱们想要取得其中的2个值:loading与clicked时:浏览器

 

// es5
var loading = props.loading;
var clicked = props.clicked;

// es6
let { loading, clicked } = props;

// 给一个默认值,当props对象中找不到loading时,loading就等于该默认值
let { loading = false, clicked } = props;
二、数组的解构赋值
// es6
let arr = [1, 2, 3];
let [a, b, c] = arr;

// es5
var arr = [1, 2, 3];
var a = arr[0];
var b = arr[1];
var c = arr[2];

数组以序列号一一对应,这是一个有序的对应关系。
而对象根据属性名一一对应,这是一个无序的对应关系,属性名一致便可。根据这个特性,使用解析结构从对象中获取属性值更加具备可用性。
ES6解构赋值

3、函数

一、箭头函数(array function)
// es5
var fn = function(a, b) {
    return a + b; 
}
// es6 箭头函数写法,当函数直接被return时,能够省略函数体的括号
const fn = (a, b) => a + b;
// es5 var foo = function() {
  var a = 20;
  var b = 30;
  return a + b; 
}
// es6 const foo = () => {
  const a = 20;
  const b = 30;
  return a + b; 
}

二、形参默认值(default)服务器

ES5的默认值写法
  
function sum(x,y){
         x=x||10;
         y=y||20;
  return x+y;
 }

 

ES6的默认值写法:数据结构

function sum(x = 10, y = 20) {
    return x + y;
}

console.log(add());

注意:一、箭头函数是匿名函数,不能做为构造函数,不能使用new

let FunConstructor = () => {
    console.log('lll');
}

let fc = new FunConstructor();

二、箭头函数中,没有本身的this。若是你在箭头函数中使用了this,那么该this必定就是外层的this,是定义时所在的对象,而不是使用时所在的对象。也正是由于箭头函数中没有this,所以咱们也就无从谈起用call/apply/bind来改变this指向。这个特性解决了函数中this指向的问题。
var obj = {
  a: 10,
  b: () => {
    console.log(this.a); // undefined
    console.log(this); // Window {postMessage: ƒ, blur: ƒ, focus: ƒ, close: ƒ, frames: Window, …}
  },
  c: function() {
    console.log(this.a); // 10
    console.log(this); // {a: 10, b: ƒ, c: ƒ}
  }
}
obj.b(); 
obj.c();
复制代码
复制代码
var obj = {
  a: 10,
  b: function(){
    console.log(this.a); //10
  },
  c: function() {
     return ()=>{
           console.log(this.a); //10
     }
  }
}
obj.b(); 
obj.c()();
三、 箭头函数不绑定arguments,取而代之用rest参数...解决
function A(a){
  console.log(arguments);
}
A(1,2,3,4,5,8);  //  [1, 2, 3, 4, 5, 8, callee: ƒ, Symbol(Symbol.iterator): ƒ]


let B = (b)=>{
  console.log(arguments);
}
B(2,92,32,32);   // Uncaught ReferenceError: arguments is not defined


let C = (...c) => {
  console.log(c);
}
C(3,82,32,11323);  // [3, 82, 32, 11323]

4、新增的数据类型

从新复习下旧知识:基本数据类型有6种:Undefined、Null、布尔值(Boolean)、字符串(String)、数值(Number)、对象(Object)。

一、Set  (相似数组)

主要用来去除重复的数据,Set 自己是一个构造函数,用来生成 Set 数据结构。

let set = new Set(["name1","zhang","wang","name1","zhang"]);
console.log(set);  //"name1","zhang","wang"

console.log(set);  //3

四个方法:add(),delete(),has(),clear()

二、Map(映射,相似对象)

(1)也是键值对的集合,可是“键”的范围不限于字符串,各类类型的值(包括对象)均可以看成键。
const map1 = new Map()
const objkey = {p1: 'v1'}

map1.set(objkey, 'hello')
console.log(map1.get(objkey))

结果:

hello

(2)Map能够接受数组做为参数,数组成员仍是一个数组,其中有两个元素,一个表示键一个表示值。

const map2 = new Map([
  ['name', 'Aissen'],
  ['age', 12]
])
console.log(map2.get('name'))
console.log(map2.get('age'))

结果:

Aissen
12

若是 Map 的键是一个简单类型的值(数字、字符串、布尔值),则只要两个值严格相等,Map 将其视为一个键,包括0和-0,布尔值true和字符串true则是两个不一样的键。另外,undefined和null也是两个不一样的键。虽然NaN不严格相等于自身,但 Map 将其视为同一个键。

三、symbol(惟一的属性名)

经常使用于对象的属性名,不会出现属性名冲突的现象。

Symbol函数前不能使用new命令,不然会报错。这是由于生成的Symbol是一个原始类型的值,不是对象

Symbol函数能够接受一个字符串做为参数,表示对Symbol实例的描述,主要是为了在控制台显示,或者转为字符串时,比较容易区分。

复制代码
// 没有参数的状况
var s1 = Symbol();
var s2 = Symbol();

s1 === s2 // false

// 有参数的状况
var s1 = Symbol("foo");
var s2 = Symbol("foo");

s1 === s2 // false
复制代码

Symbol值不能与其余类型的值进行运算

5、新增的语法糖

一、class, extends, super

      这三个特性涉及了ES5中最使人头疼的的几个部分:原型、构造函数,继承

复制代码
class Animal {
    constructor(){
        this.type = 'animal'
    }
    says(say){
        console.log(this.type + ' says ' + say)
    }
}

let animal = new Animal()
animal.says('hello') //animal says hello

class Cat extends Animal {
    constructor(){
        super()
        this.type = 'cat'
    }
}

let cat = new Cat()
cat.says('hello') //cat says hello
复制代码

  上面代码首先用class定义了一个“类”,能够看到里面有一个constructor方法,这就是构造方法,而this关键字则表明实例对象

  简单地说,constructor内定义的方法和属性是实例对象本身的,而constructor外定义的方法和属性则是全部实例对象能够共享的

  Class之间能够经过extends关键字实现继承,这比ES5的经过修改原型链实现继承,要清晰和方便不少。上面定义了一个Cat类,该类经过extends关键字,继承了Animal类的全部属性和方法。

  super关键字,它指代父类的实例(即父类的this对象)。子类必须在constructor方法中调用super方法,不然新建实例时会报错。这是由于子类没有本身的this对象,而是继承父类的this对象,而后对其进行加工。若是不调用super方法,子类就得不到this对象。

  ES6的继承机制,实质是先创造父类的实例对象this(因此必须先调用super方法),而后再用子类的构造函数修改this。

  P.S 若是你写react的话,就会发现以上三个东西在最新版React中出现得不少。建立的每一个component都是一个继承React.Component的类。

6、内置对象扩展

一、模板字符串(template string)

你们能够先看下面一段代码:

$("#result").append(
  "There are <b>" + basket.count + "</b> " +
  "items in your basket, " +
  "<em>" + basket.onSale +
  "</em> are on sale!"
);

  咱们要用一堆的'+'号来链接文本与变量,而使用ES6的新特性模板字符串``后,咱们能够直接这么来写:

$("#result").append(`
  There are <b>${basket.count}</b> items
   in your basket, <em>${basket.onSale}</em>
  are on sale!
`);

  用反引号(\来标识起始,用 ${}  来引用变量,并且全部的空格和缩进都会被保留在输出之中

二、数组扩展(Array.from和Array.of)

(1)Array.from是将伪数组对象或可迭代对象转为数组实例

let m = new Map([[1, 2], [2, 4], [4, 8]]);
Array.from(m); 
// [[1, 2], [2, 4], [4, 8]]
function f() {
  return Array.from(arguments);
}
f(1, 2, 3);
// [1, 2, 3]
Array.from([1, 2, 3], x => x + x);      
// [2, 4, 6]

// Generate a sequence of numbers
// Since the array is initialized with `undefined` on each position,
// the value of `v` below will be `undefined`
Array.from({length: 5}, (v, i) => i);
// [0, 1, 2, 3, 4]
//数组去重合并
function combine(){ let arr
= [].concat.apply([], arguments); //concat() 方法用于链接两个或多个数组。该方法不会改变现有的数组,仅仅返回被链接数组的一个副本。

return Array.from(new Set(arr));
} 

var m = [1, 2, 2], n = [2,3,3]; 
console.log(combine(m,n));                     // [1, 2, 3]

(2)Array.of是将零散的东西集合成一个数组,

Array.of(element0[, element1[, ...[, elementN]]])
Array.of(7);       // [7] 
Array.of(1, 2, 3); // [1, 2, 3]

Array(7);          // [ , , , , , , ]
Array(1, 2, 3);    // [1, 2, 3]

兼容旧环境:若是原生不支持的话,在其余代码以前执行如下代码会建立 Array.of() 。

if (!Array.of) {
  Array.of = function() {
    return Array.prototype.slice.call(arguments);
  };
}

 

三、对象的扩展

(1)key和value相同时,写一个就够了。

(2)Object.assign(),将多个对象合为一个对象

     let obj1={name:"July"};

  let obj2={age:18};

  console.log(Object.assign(obj1,obj2))   //{name:"July",age:18}

四、延展操做符(三点式)

 常见用法:(1)、复制数组和复制对象;(2)、合并数组和合并对象
const a = {a: 1, b: 2} const b = {b: 3, c: 4} console.log({...a, ...b, c: 5}) // {a: 1, b: 3, c: 5} // 至关于 Object.assign(a, b, {c: 5})

7、import export

  这两个家伙对应的就是es6本身的module功能。

  咱们以前写的Javascript一直都没有模块化的体系,没法将一个庞大的js工程拆分红一个个功能相对独立但相互依赖的小工程,再用一种简单的方法把这些小工程链接在一块儿。

  这有可能致使两个问题:

  (1)一方面js代码变得很臃肿,难以维护

  (2)另外一方面咱们经常得很注意每一个script标签在html中的位置,由于它们一般有依赖关系,顺序错了可能就会出bug

  在es6以前为解决上面提到的问题,咱们得利用第三方提供的一些方案,主要有两种CommonJS(服务器端)和AMD(浏览器端,如require.js)。

  而如今咱们有了es6的module功能,它实现很是简单,能够成为服务器和浏览器通用的模块解决方案。

  ES6模块的设计思想,是尽可能的静态化,使得编译时就能肯定模块的依赖关系,以及输入和输出的变量。CommonJS和AMD模块,都只能在运行时肯定这些东西。

  上面的设计思想看不懂也不要紧,咱先学会怎么用,等之后用多了、熟练了再去研究它背后的设计思想也不迟!

传统的写法

  首先咱们回顾下require.js的写法。假设咱们有两个js文件: index.jscontent.js,如今咱们想要在index.js中使用content.js返回的结果,咱们要怎么作呢?

  首先定义:

//content.js
define('content.js', function(){
    return 'A cat'; })

而后require:

//index.js
require(['./content.js'], function(animal){
    console.log(animal);   //A cat
})

那CommonJS是怎么写的呢?

//index.js
var animal = require('./content.js')

//content.js
module.exports = 'A cat'

ES6的写法

//index.js
import animal from './content'

//content.js
export default 'A cat'

  以上我把三者都列出来了,妈妈不再用担忧我写混淆了...

ES6 module的其余高级用法

//content.js

export default 'A cat' export function say(){ return 'Hello!' } export const type = 'dog' 

上面能够看出,export命令除了输出变量,还能够输出函数,甚至是类(react的模块基本都是输出类)

//index.js

import { say, type } from './content' let says = say() console.log(`The ${type} says ${says}`) //The dog says Hello

这里输入的时候要注意:大括号里面的变量名,必须与被导入模块(content.js)对外接口的名称相同

  若是还但愿输入content.js中输出的默认值(default),能够写在大括号外面。

//index.js

import animal, { say, type } from './content' let says = say() console.log(`The ${type} says ${says} to ${animal}`) //The dog says Hello to A cat

修改变量名

  此时咱们不喜欢type这个变量名,由于它有可能重名,因此咱们须要修改一下它的变量名。在es6中能够用 as 实现一键换名。(有点相似sql语句,哈哈)

//index.js

import animal, { say, type as animalType } from './content' let says = say() console.log(`The ${animalType} says ${says} to ${animal}`) //The dog says Hello to A cat

模块的总体加载

  除了指定加载某个输出值,还可使用总体加载,即用星号(*)指定一个对象,全部输出值都加载在这个对象上面。一般 星号结合 as 一块儿使用比较合适。

//index.js

import animal, * as content from './content' let says = content.say() console.log(`The ${content.type} says ${says} to ${animal}`) //The dog says Hello to A cat

想更全面了解ES6伙伴们能够去看阮一峰所著的电子书ECMAScript 6入门

相关文章
相关标签/搜索