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入門

相關文章
相關標籤/搜索