1. 程式人生 > >ES6特性例項

ES6特性例項

2018-07-09

概述

ECMAScript (ES) 是由 ECMAScript International標準化的指令碼語言. js一般用於客戶端指令碼。nodejs讓javascript語言可以用於伺服器端程式設計。

JavaScript由 網景(Netscape Communications Corporation)公司的開發者Brendan Eich在 1995年發明。JavaScript 早期叫 Mocha, 曾用名 LiveScript ,後正式改名 JavaScript.

ECMA Script6實現包含下列特性:

  • Support for constants
  • Block Scope
  • Arrow Functions
  • Extended Parameter Handling
  • Template Literals
  • Extended Literals
  • Enhanced Object Properties
  • De-structuring Assignment
  • Modules
  • Classes
  • Iterators
  • Generators
  • Collections
  • New built in methods for various classes
  • Promises

ECMAScript 2015(ES6) 特性分三類:

  • 完全支援:V8支援的穩定特性
  • 基本支援:基本開發完成,但V8還未穩定支援
  • 開發中: 只用於測試目的

變數

提升hoisting

Javascript 預設會將變數和函式宣告提升到最上面。但嚴格模式(Strict Mode)不做提升。

var,let和const

var 可以重複定義 let 作用於一個範圍,該範圍內不能重複定義變數。 const 和let對應,定義常量。常量地址不可修改

函式

匿名遞迴 Anonymous Recursive Function

用一對()呼叫自身。沒有()會報錯。

(function() { 
   var msg = "Hello World" 
   console.log(msg)
})()//Hello World

蘭姆達函式Lambda Function

lamda函式是一種簡潔替代匿名函式的方案,又叫箭頭函式。 包含三部分:引數,箭頭(=>),語句(函式體)

var foo = (x)=>10+x 
console.log(foo(10)

var msg = x=> { 
   console.log(x) 
} 
msg(10)

var disp = ()=>console.log("Hello World") 
disp();

立即呼叫函式 IIFE

Immediately Invoked Function Expressions (IIFEs) 立即呼叫函式可以避免變數提升(hoisting)。該模式叫自執行匿名函式 self-executing anonymous function。

var main = function() { 
   var loop = function() { 
      for(var x = 0;x<5;x++) {
         console.log(x); 
      } 
   }(); 
   console.log("x can not be accessed outside the block scope x value is :"+x); 
} 
main();
//OR
var main = function() { 
   (function() { 
      for(var x = 0;x<5;x++) { 
         console.log(x); 
      } 
   })(); 
   console.log("x can not be accessed outside the block scope x value is :"+x); 
} 
main();

生成函式

  • 函式前帶*.
  • 函式可以在需要的地方生成值,供呼叫者使用
  • 呼叫時會返回迭代器,迭代器的.next()才真正執行。返回一個value和一個done,如果done為true,則生成器結束。否則可以繼續呼叫.next().
"use strict" 
function* rainbow() { 
   // the asterisk marks this as a generator 
   yield 'red'; 
   yield 'orange'; 
   yield 'yellow'; 
   yield 'green'; 
   yield 'blue'; 
   yield 'indigo'; 
   yield 'violet'; 
} 
for(let color of rainbow()) { 
   console.log(color); 
} 

function* ask() { 
   const name = yield "What is your name?"; 
   const sport = yield "What is your favorite sport?"; 
   return `${name}'s favorite sport is ${sport}`; 
}  
const it = ask(); 
console.log(it.next()); 
console.log(it.next('Ethan'));  
console.log(it.next('Cricket')); 

cookie

cookie不可包含”;,”和空格。如果要存這些符號,必須用escape函式處理。

Cookies 是純文字資料,由5種可變長欄位構成:

  • Expires − The date the cookie will expire. If this is blank, the cookie will expire when the visitor quits the browser.
  • Domain − The domain name of your site.
  • Path − The path to the directory or web page that sets the cookie. This may be blank, if you want to retrieve the cookie from any directory or page.
  • Secure − If this field contains the word “secure”, then the cookie may only be retrieved with a secure server. If this field is blank, no such restriction exists.
  • Name = Value − Cookies are set and retrieved in the form of key-value pairs.

儲存cookie

<html> 
   <head> 
      <script type ="text/javascript">  
         function WriteCookie() {
         var now = new Date(); 
         now.setMonth( now.getMonth() + 1 );
         //設定到過去可以刪除cookie
         //now.setMonth( now.getMonth() - 1 ); 
            if( document.myform.customer.value == "" ){  
               alert ("Enter some value!");  
               return;  
            }  
            cookievalue =  escape(document.myform.customer.value) + ";";  
            document.cookie = "name = " + cookievalue; 
            document.cookie = "expires = " + now.toUTCString() + ";" 
            document.write ("Setting Cookies : " + "name = " + cookievalue );  
         }  
      </script> 
   </head> 
      
   <body> 
      <form name ="myform" action =""> 
         Enter name: <input type ="text" name ="customer"/> 
         <input type ="button" value ="Set" onclick ="WriteCookie();"/> 
      </form> 
   </body> 
</html>

讀取cookie

用split分隔值和key。

<html> 
   <head> 
      <script type ="text/javascript"> 
         function ReadCookie() {  
            var allcookies  =  document.cookie;  
            document.write ("All Cookies : " + allcookies ); 
         } 
         // Get all the cookies pairs in an array  
         cookiearray = allcookies.split(';');  
         
         // Now take key value pair out of this array  
         for(var i = 0; i<cookiearray.length; i++) {  
            name  =  cookiearray[i].split('=')[0];  
            value = cookiearray[i].split('=')[1];  
            document.write ("Key is : " + name + " and Value is : " + value); 
         }  
      </script> 
   </head> 

   <body> 
      <form name ="myform" action =""> 
         <p> click the following button and see the result:</p> 
         <input type ="button" value ="Get Cookie" onclick ="ReadCookie()"/> 
      </form> 
   </body> 
</html> 

物件

Js支援擴充套件資料型別。Object是包含很多key value對的例項。這些鍵值對可以是複雜型別,並且在生命週期中可以改變。

構造

屬性由name和value組成。

var identifier={
     Key1:"123abc",//properties or members
    Key2: function () { 
      //functions
      console.log("hello")
   }, 
   Key3: ["content1"," content2"] 

}

es6 可以省略物件的值

var foo = 'bar' 
var baz = { foo } 
console.log(baz.foo)

es5 不能省

var foo = 'bar' 
var baz = { foo:foo } 
console.log(baz.foo)

可以用Object作為物件的建構函式。

var obj_name = new Object(); 
obj_name.property = value;    
//OR             
obj_name["key"] = value 

Object_name.property_key                    
//OR              
Object_name["property_key"]

var myCar = new Object(); 
myCar.make = "Ford"; //define an object 
myCar.model = "Mustang"; 
myCar.year = 1987;  

console.log(myCar["make"]) //access the object property 
console.log(myCar["model"]) 
console.log(myCar["year"])

Using a Function Constructor

function Car() { 
   this.make = "Ford" 
   this.model = "F123" 
}  
var obj = new Car() 
console.log(obj.make) 
console.log(obj.model)

模板字面量Template Literals

用反引號``和${}

var name = "Brendan"; 
console.log('Hello, ${name}!'); //Hello, Brendan!

//expressions
var a = 10; 
var b = 10; 
console.log(`The sum of ${a} and ${b} is  ${a+b} `);//The sum of 10 and 10 is  20 

//function expressions
function fn() { return "Hello World"; } 
console.log(`Message: ${fn()} !!`);//Message: Hello World !!

//multiline
var multiLine = ` 
   This is 
   a string 
   with \n multiple 
   lines`; 
console.log(multiLine)
/*
   This is 
   a string 
   with 
 multiple 
   lines
   */
//raw string   
var raw_text = String.raw`Hello \n World ` 
console.log(raw_text)//Hello \n World

陣列

var numbers = [4, 5, 6];
var val = numbers.entries(); 
console.log(val.next().value);  
console.log(val.next().value);  
console.log(val.next().value);
/*
[0, 4]
[1, 5]
[2, 6]
*/
var val= numbers.entries(); 
console.log([...val]);
/*
[ [0, 4]
 [1, 5]
 [2, 6]]
*/
//
"use strict" 
var nums = [1001,1002,1003,1004] 
for(let j in nums) { 
   console.log(nums[j]) 
}
//Array Traversal using for…in loop
console.log(Array.from(['a', 'b'].keys()))
//[ 0, 1 ] 

//Array De-structuring
var arr = [12,13] 
var[x,y] = arr 
console.log(x) 
console.log(y)
//12
//13

正則

var pt=new RegExp("人民$",RegExp.U)
pt.test("中國人民愛人民")
//true
//OR
/人民$/u.test("中國人民愛人民")
//true
/人民/.test("中國人")
//false

HTML DOM

dom

集合

  • Maps
  • Sets
var map = new Map(); 
map.set(1,true); 
console.log(map.has("1")); //false 

map.set("1",true); 
console.log(map.has("1")); //true

var roles = new Map([ 
   ['r1', 'User'], 
   ['r2', 'Guest'], 
   ['r3', 'Admin'], 
]);  
console.log(roles.get('r2'))

// for ...Of loop
'use strict' 
var roles = new Map([ 
   ['r1', 'User'], 
   ['r2', 'Guest'], 
   ['r3', 'Admin'], 
]);
for(let r of roles.entries()) 
console.log(`${r[0]}: ${r[1]}`);
/*
r1: User 
r2: Guest 
r3: Admin
*/

面向物件是一種對現實世界建模的程式設計正規化。由一系列物件組成,並由方法進行通訊。

  • Object − An object is a real-time representation of any entity. According to Grady Brooch, every object is said to have 3 features −

    • State − Described by the attributes of an object.

    • Behavior − Describes how the object will act.

    • Identity − A unique value that distinguishes an object from a set of similar such objects.

  • Class − A class in terms of OOP is a blueprint for creating objects. A class encapsulates data for the object.

  • Method − Methods facilitate communication between objects.

A class definition can include the following −

  • Constructors − Responsible for allocating memory for the objects of the class.

  • Functions − Functions represent actions an object can take. They are also at times referred to as methods.

不像變數和函式,類不能提升hoisting

//A class body can only contain methods, but not data properties.

// Declaring a class
class Polygon { 
   constructor(height, width) { 
      this.height = height; 
      this.width = width; 
   } 
}

//Class Expression
//unamed class
var Polygon = class { 
   constructor(height, width) { 
      this.height = height; 
      this.width = width; 
   } 
}

'use strict' 
class Person{ } 
var obj = new Person() 
var isPerson = obj instanceof Person; 
console.log(" obj is an instance of Person " + isPerson); 

//ES6不支援多繼承,但支援多層
// extends 和this,super關鍵字
'use strict' 
class Root { 
    constructor(a) {
        this.root=a
    }
   test() { 
      console.log("call from parent class") 
   } 
} 
class Child extends Root {
    constructor(a,b) {
        super(a)
        this.b=b;
    }
    test() {
        super.test();
        console.log("call from Child class");
    }
} 
class Leaf extends Child   

//indirectly inherits from Root by virtue of inheritance {} 
var obj = new Leaf();
obj.test() 

Promise

Promise 是ES6 非同步程式設計的新特性。 此前的非同步程式設計採用callback方式。

同步程式設計

function notifyAll(fnSms, fnEmail) {   
      console.log('starting notification process');   
      fnSms();   
      fnEmail();   
   }   
   notifyAll(function() {   
      console.log("Sms send ..");   
   }, 
   function() {   
      console.log("email send ..");   
   });   
   console.log("End of script"); 
   //executes last or blocked by other methods  

setTimeout非同步程式設計

setTimeout引數為一個需要執行的函式和多久後執行,單位毫秒

function notifyAll(fnSms, fnEmail) {   
      setTimeout(function() {   
         console.log('starting notification process');   
         fnSms();   
         fnEmail();   
      }, 2000);   
   }   
   notifyAll(function() {   
      console.log("Sms send ..");   
   },  
   function() {   
      console.log("email send ..");   
   });   
   console.log("End of script"); //executes first or not blocked by others   

多重呼叫的程式碼很難看明白。

   setTimeout(function() {   
      console.log("one");   
      setTimeout(function() {   
         console.log("two");   
         setTimeout(function() {   
            console.log("three");   
         }, 1000);   
      }, 1000);   
   }, 1000);   

## Promise Promise是連續事件集(Continuation events) 可以用乾淨程式碼實現多重非同步操作。

 var promise = new Promise(function(resolve , reject) {    
   // do a thing, possibly async , then..  
   if(/*everthing turned out fine */)    resolve("stuff worked");  
   else     
   reject(Error("It broke"));  
});  
return promise;
// Give this to someone

非同步求和示例

 function asum(n1, n2) {   
   var isAnyNegative = function() {   
      return n1 < 0 || n2 < 0;   
   }   
   var promise = new Promise(function(resolve, reject) {   
      if (isAnyNegative()) {   
         reject(Error("Negatives not supported"));   
      }   
      resolve(n1 + n2)
   });   
   return promise;   
} 

//The caller should use the ‘then’ method, which takes two callback methods - first for success and second for failure. Each method takes one parameter
asum(5, 6)   
.then(function (result) {   
   console.log(result);   
},   
function (error) {   
   console.log(error);   
});

//多重連續呼叫
aum(5, 6)   
.then(function(result) { //第一重then 處理
   console.log(result);   
   return asum(result, 20); //此處必須用return,下一層then才能拿到結果
   //繼續返回promise,在下一層接著處理
   // this returns another promise   
},   
function(error) {   
   console.log(error);   
})   
.then(function(result) {   //第二重then處理
   console.log(result);   
}, 
function(error) {   
   console.log(error);
});   
//11
//31

模組Modules

模組可以讓你僅暴露需要暴露的部分。 程式碼複用時,模組就發揮重要作用。定義在檔案中的函式和變數,外部並不能使用。除非將他們匯出 export。 目前ES6 模組必須要轉編譯(Transpilation)ES5 ,才可以執行和測試。 ES6 Module Transpiler可以將ES6的模組轉為ES5相容的CommonJS或AMD樣式。 可以使用 Grunt, Gulp, Babel 來轉為ES5格式。

匯出模組

單個匯出

export default element

多個匯出

export {name1,name2,...}

匯入

import ele from module1
import {name1,name2,...} from module

測試程式碼

[email protected]/Users/zhouhh/test1 $ npm install -g es6-module-transpiler
[email protected]/Users/zhouhh/test1 $ mkdir out
[email protected]/Users/zhouhh/test1 $ find .
.
./out
./msg.js
./main.js
./calc.js

[email protected]/Users/zhouhh/test1 $ cat msg.js
var msg=function(value){
    console.log(`hello ${value}`)
}
export default msg
[email protected]/Users/zhouhh/test1 $ cat calc.js
var sum=(a,b)=>a+b
var times=(a,b)=>a*b

export {sum,times}
[email protected]/Users/zhouhh/test1 $ cat main.js
import test1 from "./msg.js"
import {sum,times} from "./calc.js"
console.log(sum(3,2))
console.log(times(4,2))
test1("中國")

[email protected]/Users/zhouhh/test1 $ node main.js
/Users/zhouhh/test1/main.js:1
(function (exports, require, module, __filename, __dirname) { import test1 from "./msg.js"
                                                              ^^^^^^

SyntaxError: Unexpected token import

[email protected]/Users/zhouhh/test1 $ compile-modules convert -I . -o out *.js -f commonjs
[email protected]/Users/zhouhh/test1 $ node out/main.js
5
8
hello 中國



參考

es6 入門

如非註明轉載, 均為原創. 本站遵循知識共享CC協議,轉載請註明來源