ES6特性实例

周海汉 2018-07-09
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

测试代码

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

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

export {sum,times}
zhouhh@/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("中国")

zhouhh@/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

zhouhh@/Users/zhouhh/test1 $ compile-modules convert -I . -o out *.js -f commonjs
zhouhh@/Users/zhouhh/test1 $ node out/main.js
5
8
hello 中国



参考

es6 入门


如非注明转载, 均为原创. 本站遵循知识共享CC协议,转载请注明来源