基本語法html
ES6 新增了 let
命令,用來聲明變量。它的用法相似於 var
,區別在於 let
命令聲明的變量只在 let
命令所在的代碼塊內有效。node
不存在變量提高ajax
let
不像 var
那樣,會發生「變量提高」現象。json
暫時性死區數組
只要塊級做用域內存在 let
命令,它所聲明的變量就 」綁定(binding)」 這個區域,再也不受外部的影響。瀏覽器
不容許重複聲明數據結構
let
不容許在相同做用域內,重複聲明同一個變量。async
爲何須要塊級做用域?函數
ES5 只有全局做用域和函數做用域,沒有塊級做用域,這帶來不少不合理的場景。jsonp
第一種場景:內層變量可能會覆蓋外層變量。
第二種場景:用來計數的循環變量泄露爲全局變量。
ES6 的塊級做用域
let
實際上爲 JavaScript 新增了塊級做用域。
當即執行函數
(function () {}()); 複製代碼
const
也用來聲明變量,可是聲明的是常量。一旦聲明,常量的值就不能改變。const
聲明的常量只在當前代碼塊有效。
聲明凍結對象(也就是說對象的成員變量的值也不能夠改變)
const person = Object.freeze({
name: "zhangsan",
age: 20
});
複製代碼
完全凍結對象的函數
freeze.js
var constantize = (obj) => {
Object.freeze(obj);
Object.keys(obj).forEach((key, value) => {
if(typeof obj[key] === 'object') {
constantize(obj[key]);
}
})
};
複製代碼
moduleA.js
export const HOST = "http://www.xxx.com";
export const PORT = 8080;
export const NAME = "Lark";
在 moduleB.js 中要如何使用 moduleA.js 中的 HOST 常量呢?
moduleB.js
// * 表示所有引入
import * as ma from "./moduleA";
// 這樣使用moduleA中的變量
console.log(ma.HOST);
// 部分引入
import { HOST, PORT } as ma from "./moduleA";
console.log(ma.HOST, ma.PORT);
// 只引入一個
import NAME as ma from "./moduleA";
console.log(ma.NAME);
複製代碼
全局對象是最頂層的對象,在瀏覽器環境指的是 window
對象,在 node.js 中指的是 global
對象,在 JavaScript 語言中,全部全局變量都是全局對象的屬性。(node 的狀況比較特殊,這一條只對 REPL 環境適用,模塊環境必須顯式聲明成 global 的屬性)
ES6 規定,var
和 function
命令聲明的全局變量,屬於全局對象的屬性;let
、const
、class
命令聲明的全局變量,不屬於全局對象的屬性。
例如:
var varName = "varValue";
// 瀏覽器環境下
console.log(window.varName);
// node.js環境下
console.log(global.varName);
// 通用環境下
console.log(this.varName);
複製代碼
Destructuring
ES6 容許按照必定模式,從數組和對象中提取值,對變量進行賦值,這被稱爲解構(Destructuring)。
不徹底解構
等號左邊的模式,只匹配一部分的等號右邊的數組。
指定默認值
注意:ES6內部使用嚴格相等運算符(===)判斷一個位置是否有值。因此,若是一個數組成員不嚴格等於undefined
,默認值是不會生效的。
let
和 const
命令
只要某種數據結構具備 iterator
接口,均可以採用數組形式的解構賦值。
// Destructuring
// ES6
var [a, b, c] = [1, 2, 3];
console.log(a, b, c);// 1 2 3
//不徹底解構
var [first, second] = [1];
console.log(first); //1
console.log(second); //undifined
//指定默認值
var [one = "One", two] = [];
console.log(one); // One
console.log(two); // undefined
var [x = "abc", y] = [undefined, "xyz"];
console.log(x); //abc 由於undefined表示沒有值,因此並不會覆蓋abc
console.log(y); //xyz
// iterator 接口
let [a, b, c] = new Set(["a", "b", "c"]);
console.log(a); //a
console.log(b); //b
console.log(c); //c
function* fibs() {
let a = 0;
let b = 1;
while(true) {
yield a;
[a, b] = [b, a + b];
};
var [first, second, third, fourth, fifth, sixth] = fibs();
console.log(sixth); //5
}
複製代碼
解構不只能夠用於數組,還能夠用於對象
對象的屬性沒有次序,變量必須於屬性同名,才能取到正確的值。
指定默認值
默認值生效的條件是:對象的屬性值嚴格等於undefined
(也就是說若是有值的話,默認值就不會生效)。
現有對象的方法
對象的解構賦值,能夠很方便地將現有對象的方法賦值到某個變量。
var {name, age} = {name: "Lark", age: 30};
console.log(name, age); // Lark 30
複製代碼
若是變量名和屬性名不一致,該如何調用?
var {name: pName, age: pAge} = {name: "Lark", age: 30};
console.log(pName, pAge); // Lark 30
複製代碼
指定默認值
var { x = 3 } = {};
console.log(x); // 3
var { y = 4 } = { y = undefined };
console.log(y); // 4
var { z = 5 } = { z = null };
console.log(z); // null
複製代碼
對已聲明變量的解構賦值
var x;
{ x } = { x: 1 };
console.log(x); // 報錯 語法錯誤,編譯不經過
var y;
({ y } = { y: 1 });
console.log(y); // 1
複製代碼
現有對象的方法(使用現有對象的方法,就不用每次對象.方法
方式調用了)
let { sin, cos, tan, PI } = Math;
console.log(sin(PI / 6)); // 0.49999999
複製代碼
字符串也能夠解構賦值
字符串被轉換成了一個相似於數組的對象
屬性解構賦值
相似數組的對象都有一個 length
屬性,所以還能夠對這個屬性解構賦值。
var { a, b, c, d, e } = "hello";
console.log(a, b, c, d, e); // h e l l o
複製代碼
字符串的屬性解構
const { length: len } = "hello";
console.log(len); // 5
複製代碼
函數參數的解構賦值
function sum([x, y]) {
return x + y;
}
console.log(sum([1, 3])); // 4
複製代碼
函數參數解構賦值的默認值
function sum({x = 0, y = 0} = {}) {
return [x, y];
}
console.log(sum({x: 100, y: 200})); // [100, 200]
console.log(sum({x: 100})); // [100, 0]
console.log(sum({})); // [0, 0]
console.log(sum()); //[0, 0]
複製代碼
function sum({x, y} = {x: 0, y: 0}) {
return [x, y];
}
console.log(sum({x: 100, y: 200})); // [100, 200]
console.log(sum({x: 100})); // [100, undefined]
console.log(sum({})); // [undefined, undefined]
console.log(sum()); //[0, 0] 沒有傳參數,它作的不是函數參數解構賦值,而是對象解構賦值,{x, y} = {x: 0, y: 0} 會在函數運行。
複製代碼
交換變量的值
var x = 100;
var y = 200;
[x, y] = [y, x];
console.log(x, y); // 200 100
複製代碼
從函數返回多個值
function fun() {
return [1, 2, 3];
}
var [x, y, z] = fun();
console.log(x, y, z); // 1 2 3
複製代碼
function fun() {
return {
id: "001",
name: "Lark",
age: 30
};
}
var { id, name, age } = fun();
console.log(id, name, age); // 001 Lark 30
複製代碼
函數參數的定義
// 參數是一組有次序的值
function fun([x, y, z]) {
// x=100 y=200 z=300
}
fun([100, 200, 300]);
// 參數是一組無次序的值
function fun2({id, name, age}) {
// id="001" name="Lark" age=30
}
fun2({id: "001", name: "Lark", age: 30});
複製代碼
提取json數據
var jsonData = {
id: "001",
name: "Lark",
age: 30,
score: {
Chinese: 100,
English: 90
}
};
let { id, name, age, score } = jsonData;
console.log(id, name, age, score);// 001 Lark 30
複製代碼
函數參數的默認值
jQuery.ajax({
url: '/path/to/file',
type: 'POST',
dataType: 'xml/html/script/json/jsonp',
data: {param1: 'value1'},
complete: function(xhr, textStatus) {
},
success: function(data, textStatus, xhr) {
},
error: function(xhr, textStatus, errorThrown) {
}
});
jQuery.ajax = function(url, { async = true, beforeSend = function() {},
cache = true,
complete = function() {},
crossDomain = false,
global = true
}){
// do something
};
複製代碼
遍歷map解構
var map = new Map();
map.set("id", "001");
map.set("name", "Lark");
map.set("age", 30);
// 獲取鍵名和鍵值
for(let [key, value] of map) {
console.log(key, value);
}
// id 001
// name Lark
// age 30
// 獲取鍵名
for(let [key] of map) {
console.log(key);
}
// id
// name
// age
// 獲取鍵值
for(let [, value] of map) {
console.log(value);
}
// 001
// Lark
// 30
複製代碼
輸入模塊的指定方法
const { SourceMapConsumer, SourceNode } = require("source-map");
複製代碼
後面會持續更新請繼續關注,再會......