JavaScript的第六版,在ES5的基礎上增長了許多特性:箭頭函數、字符串插值、代理、生成器、結構賦值、塊級做用域等等。
ES6
中明確規定,若是區塊中存在let
和const
命令,則這個區塊對這些命令聲明的變量從一開始就造成封閉做用域。只要在聲明以前就使用這些變量,就會報錯(暫時性死區)。javascript
let
聲明的變量做用域不會被提高for
循環體現let
的父子做用域const
聲明一個只讀的常量let [name, age, sex] = ['李四', 20, '女']; console.log(name); // 李四 console.log(age); // 20 console.log(sex); // 女
let { name, age, friends, pet } = { name: '張三', age: 55, friends: ['lulu', '王五'], pet: { name: '土豆', age: 5 } }; console.log(name); // 張三 console.log(age); // 55 console.log(friends); // ["lulu", "王五"] console.log(pet); // {name: "土豆", age: 5}
let { name: str } = { name: '張三' }; console.log(name); // console.log(str); // 張三
let [arr1, [arr2, arr3, [arr4, arr5]]] = [1, [2, 3, [4, 5]]]; console.log(arr1, arr2, arr3, arr4, arr5); // 1 2 3 4 5
let [arr1] = []; console.log(arr1); // undefined
let [a, , c] = [1, 2, 3]; console.log(a); // 1 console.log(c); // 3
let [a, b, c, d, e] = '我是中國人'; console.log(a); // 我 console.log(b); // 是 console.log(c); // 中 console.log(d); // 國 console.log(e); // 人
相似於數組,可是成員是惟一的,沒有重複。
let set = new Set(['張三', '李四', '王五', '張三', '李四']); console.log(set); //{"張三", "李四", "王五"} console.log(Array.from(set)); // ["張三", "李四", "王五"]
console.log(set.size); //3
//add console.log(set.add('劉德華').add('LHH')); //{"張三", "李四", "王五", "劉德華", "LHH"} console.log(set); //{"張三", "李四", "王五", "劉德華", "LHH"} //delete console.log(set.delete('張三')); // true console.log(set.delete('李四')); // true console.log(set); //has console.log(set.has('張三')); // true console.log(set.has('張三1')); // false //clear console.log(set.clear()); // undefined console.log(set); // {}
console.log(set.keys()); // SetIterator {"張三", "李四", "王五"} console.log(set.values()); // SetIterator {"張三", "李四", "王五"}
相似於對象,也是鍵值對集合,但「鍵」的範圍不限於字符串,各類類型的值(包括對象)均可以看成鍵.
let obj1 = { a: 1 }, obj2 = { b: 2 }; const map = new Map([ ['name', '張三'], ['age', 18], ['sex', '男'], [obj1, '今每天氣很好'], [obj2, '適合敲代碼'], [ [1, 2], 'hhh' ] ]); console.log(map); console.log(map.size);
map.set('friends', ['趙六', '力氣']).set(['dog'], '小花'); console.log(map); console.log(map.get('name')); console.log(map.get(obj1));
map.delete(obj1); console.log(map.delete('xxxx')); console.log(map);
console.log(map.has(obj1)); // true console.log(map.has(obj2)); //true
map.clear(); console.log(map); // {}
console.log(map); console.log(map.keys()); console.log(map.values()); console.log(map.entries());
map.forEach(function(value, index) { console.log(index + ':' + value); })
map.set({}, '呵呵呵呵呵'); map.set({}, '哈哈哈哈'); console.log(map); console.log({} === {});
let str1 = Symbol(); let str2 = Symbol(); console.log(str1 === str2); // false console.log(typeof str1); // symbol console.log(typeof str2); // symbol
let str3 = Symbol('name'); let str4 = Symbol('name'); console.log(str3); // Symbol(name) console.log(str4); // Symbol(name) console.log(str3 === str4); // false
const obj = {}; obj.name = '張三'; obj.name = '李四'; obj[Symbol('name')] = '張三'; obj[Symbol('name')] = '李四'; let a = Symbol('aa'); let b = Symbol('bb'); obj[a] = '王五' obj[b] = 'kk' console.log(obj); console.log(Object.getOwnPropertySymbols(obj)); // 獲取指定對象的全部Symbol屬性名 console.log(Reflect.ownKeys(obj)); // 返回全部類型的鍵名,包括常規鍵名和Symbol鍵名
注意,Symbol
函數前不能使用new
命令,由於Symbol
是一個原始類型的值,不是對象,因此也不能添加屬性。
var s1 = Symbol.for('foo'); var s2 = Symbol.for('foo'); s1===s2; // true
上面代碼中,s1
和s2
都是Symbol的值,但它們都是一樣參數的Symbol.for
方法生成的,全部其實是同一個值。html
Symbol.for()
與Symbol()
這兩種寫法都會生成新的Symbol
。它們的區別是,前者會被登記在全局環境中供搜索,然後者不會。Symbol.for()不會再每次調用時都返回一個新的Symbol
類型的值,而是會先檢查給定的key
是否已經存在,若是不存在纔會新建一個值,好比,若是調用Symbol.for('cat')30次,每次都會返回同一個Symbol
值,可是調用Symbol('cat')30次則會返回30個不一樣的Symbol
值。java
var s1 = Symbol.for("foo"); Symbol.keyFor(s1); // "foo" var s2 = Symbol("foo"); Symbol.keyFor(s2); // undefined
注:Symbol.for
爲Symbol
值登記的名字是全局環境的,能夠在不一樣的iframe
或service worker
中取到同一個值。
iframe = document.createElement('iframe'); iframe.src = String(window.location); document.body.appendchild(iframe); iframe.contentWindow.Symbol.for('foo') === Symbol.for('foo'); // true
function Person(name, age) { this.name = name; this.age = age; } Person.prototype = { constructor: Person, print(){ console.log('我叫' + this.name + ',今年' + this.age + '歲'); } }; //或 //Person.prototype.print = function() { // console.log('我叫' + this.name + ',今年' + this.age + '歲'); //} let person = new Person('張三', 19); console.log(person); person.print();
class Person { constructor(name, age) { this.name = name; this.age = age; } print() { console.log('我叫' + this.name + ',今年' + this.age + '歲'); } } let person = new Person('張三', 19); console.log(person); person.print();
class Animal { //構造函數 constructor(props) { this.name = props.name || '未知'; } eat() { alert(this.name + "在吃東西..."); } } //class繼承 class Bird extends Animal { //構造函數 constructor(props) { //調用實現父類的構造函數 super(props); this.type = props.type || "未知"; } fly() { alert(this.name + "在飛..."); } } var myBird = new Bird({ name: '鸚鵡' }) myBird.eat() // 鸚鵡在吃東西... myBird.fly() // 鸚鵡在飛...
let str = '適合敲代碼!'; let className = 'test'; let html = `<html> <head></head> <body> <p>今天的天氣很好!</p> <div class="${className}">${str}</div> </body> </html>`; console.log(html);
Array.from數組
// 在body中寫了幾個li節點 let allLis = document.querySelectorAll('li'); console.log(allLis); // NodeList(6) [li, li, li, li, li, li] console.log(Array.isArray(allLis)); // false console.log(Array.from(allLis)); // [li, li, li, li, li, li] console.log(Array.isArray(Array.from(allLis))); // true
Array.of數據結構
console.log(Array.of(1, 2, 3, 4)); // [1, 2, 3, 4] console.log(Array.of('張三', '李四', '王五')); // ["張三", "李四", "王五"]
key
和 value
是同樣的,寫一個就夠了app
let name = '張三'; let age = 18; let person = { name, age }; console.log(person); // {name: "張三", age: 18}
Object.assign()函數
let obj1 = { name: '張三' }; let obj2 = { age: 18 }; let obj3 = { sex: '男' }; let obj4 = { friends: '李四' }; let obj = {}; Object.assign(obj, obj1, obj2, obj3, obj4); console.log(Object.assign(obj, obj1, obj2, obj3, obj4)); // {name: "張三", age: 18, sex: "男", friends: "李四"} console.log(obj); // {name: "張三", age: 18, sex: "男", friends: "李四"}
延展操做符this
let str = '今天的天氣很好!'; let strArr = [...str]; console.log(strArr); // ["今", "天", "的", "天", "氣", "很", "好", "!"]
let student = { name: '張三', age: 18, sex: '男' } < Person {...student}/>
let myArr = [1, 2, 10, '張三', 20, 2, 1]; console.log(new Set(myArr)); // {1, 2, 10, "張三", 20} console.log([...new Set(myArr)]); // [1, 2, 10, "張三", 20]
function sum(num1 = 20, num2 = 10) { console.log(num1 + num2); } /* function sum(num1, num2) { num1 = num1 || 10; num2 = num2 || 10; console.log(num1 + num2); } */ sum(10, 30); // 40 sum(); // 30
function sum(name, sex, ...nums) { let result = 0; console.log(name); console.log(sex); for (let value of nums) { result += value; } return result; } /* function sum() { let result = 0; for(let value of arguments){ result += value; } return result; } */ console.log(sum('張男', '男', 10, 20, 30, 50)); // 張男 // 男 // 110
let sum = (num1, num2)=>{ return num1 + num2;}; console.log(sum(100, 300)); // 400
let nameArr = ['張三', '李四', '王五']; nameArr.forEach((value, index) => { console.log(index + ':' + value); }); // 0:張三 // 1:李四 // 2:王五
this的指向不一樣spa
function demo() { setTimeout(function() { console.log(this); }, 500); setTimeout(() => { console.log(this); }, 1000); } let obj = { a: 1 }; demo.call(obj); // Window // {a: 1}
箭頭函數的幾個注意事項:prototype
this
對象就是定義時所在的對象,而不是使用時所在的對象;new
命令,不然報錯;arguments
對象,該對象在函數體內不存在;能夠rest
參數代替(...參數);yield
命令,所以箭頭函數不能用做Generator
函數;Iterator
做用:一是爲各類數據結構提供統一的、簡便的訪問接口;二是使得數據結構的成員可以按某種次序排列;三是ES6
建立了一種新的遍歷命令——for...of
循環,Iterator
接口主要供for...of
消費
模擬next方法返回值得例子:
var it = makeIterator(['a', 'b']); console.log(it.next()); // {value: "a", done: false} console.log(it.next()); // {value: "b", done: false} console.log(it.next()); // {value: undefined, done: true} function makeIterator(array) { var nextIndex = 0; return { next: function() { return nextIndex < array.length ? { value: array[nextIndex++], done: false } : { value: undefined, done: true } } } }
Array
Map
Set
String
TypedArray
函數的arguments
對象NodeList
對象
下面例子是數組的Symbol.iterator
屬性:
let arr = ['a', 'b', 'c']; let iter = arr[Symbol.iterator](); console.log(iter.next()); // {value: "a", done: false} console.log(iter.next()); // {value: "b", done: false} console.log(iter.next()); // {value: "c", done: false} console.log(iter.next()); // {value: undefined, done: true}
注意:對象(Object
)之因此沒有默認部署Iterator
接口,是由於對象屬性的遍歷前後順序是不肯定的。
一個數據結構只要部署了Symbol.iterator
屬性,就被視爲具備Iterator
接口,就能夠用for...of
循環它的成員。
注意:有些數據結構是在現有數據結構的基礎上計算生成的,好比ES6
的數組、Set
、Map
都部署了一下三個方法,調用後都返回遍歷器對象
entries()
返回一個遍歷器對象,用於遍歷[鍵名,鍵值]組成的數組。對於數組,鍵名就是索引值;對於Set
,鍵名與鍵值相同。Map
結構的Iterator
接口默認就是調用entries
方法keys()
返回一個遍歷器對象,用於遍歷全部的鍵名values()
返回一個遍歷器對象,用於遍歷全部的鍵值