摘要:函數更好的尾遞歸優化實現傳入類數組對象且每次的值在改變。尾遞歸實現改寫一般的遞歸函數確保最后一步只調用自身。返回一個遍歷器對象用循環遍歷。和循環它是一種遍歷器接口為各種不同的數據結構提供統一的訪問機制。
解構賦值
//數組的解構賦值 let [a, b, c] = [1, 2, 3]; a // 1 b // 2 c // 3 let [a, [[b], c]] = [1, [[2], 3]]; a // 1 b // 2 c // 3 let [a, , c] = [1, 2, 3]; a // 1 c // 3 let [a, ...b] = [1, 2, 3]; a // 1 b // [2, 3] //默認值引用其他變量 let [x = 1, y = x] = []; // x = 1, y = 1 let [x = 1, y = x] = [2]; // x = 2, y = 2 let [x = 1, y = x] = [1, 2]; // x = 1, y = 2 let [x = y, y = 1] = []; // Error x用到默認值y時, y還沒被聲明。 //對象的解構賦值 let { foo: one, bar: two } = { foo: "aaa", bar: "bbb" }; one // "aaa" two // "bbb" foo // foo is not defined 對象的解構賦值是先找到同名屬性, 然后再賦值給對應的變量 let { foo, bar } = { foo: "aaa", bar: "bbb" }; //簡寫 foo // "aaa" bar // "bbb" //指定默認值 let { x, y = 5 } = { x: 1 }; x // 1 y // 5 let { x: y = 3 } = { x: 5 }; y // 5 //字符串的解構賦值 const [a, b, c, d, e] = "hello"; a // "h" b // "e" c // "l" d // "l" e // "o" let { length: len } = "hello"; len // 5 //函數參數的解構賦值 [[1, 2], [3, 4]].map(([a, b]) => a + b ); // [3, 7] //函數參數指定默認值 function desc({ x = 0, y = 0} = {}) { return [x, y]; } desc({ x: 3, y: 8 }) // [3, 8] desc({ x: 3 }) // [3, 0] desc({}) // [0, 0] desc() // [0, 0] //undefined觸發函數參數的默認值 [1, undefined, 3].map((x = "2") => x); // [1, 2, 3] /*--常見用途--*/ //交換變量 let x = 1, y = 2; [x, y] = [y, x]; //函數返回多個值 function example() { var obj = { foo: [1, 2, 3], bar: { d: 4, e: 5 } } return obj; } let { foo: [a, b, c], bar : { d, e } } = example(); //提取JSON數據 var json = { result: "success", info: { id: 22, name: "RetroAstro", avatar: "cream.png", detail: ["111", "222", "333"] } } let { result, info: { id , name, avatar, detail: [a, b, c] } } = json; //遍歷Map接口 var map = new Map([ ["first", "one"], ["second", "two"] ]); for ( let [key, value] of map.entries() ) { console.log(key, value); }模板字符串
//常用實例 var obj = { username: "RetroAstro", avatar: "user.png", info() { var x = 1, y = 2; return x + y; } } var str = `${obj.username} /g, ">"); str += template[i]; } return str; } var user = ""; safeHTML`${user} has sent you a message.
`; // "has sent you a message.
" 函數的擴展//函數參數默認值 var $ = { ajax({ method = "GET", url = "", async = true, headers = {}, encType = "", data = "", dataType = "json", success = function() {}, error = function() {} }) { // start xhr ... } } //箭頭函數 var x = 5, y = 6; var f = () => { return x + y }; //等價于 var f = () => x + y; //等價于 var f = function() { return x + y; } //rest參數和變量解構 var f = ({first, last}, ...values) => [first, values, last]; f({ first: "Retro", last: "Astro" }, 2, 3, 4, 5); // ["Retro", [2, 3, 4, 5], "Astro"] //箭頭函數中的this指向 function foo() { setTimeout(() => { console.log(this.id); }, 1000) } // 等價于 function foo() { var that = this; setTimeout(function() { console.log(that.id); }, 1000) } foo.call({id: "233"}); // 233 /* @ 箭頭函數里面根本沒有自己的this, 而是引用外層的this。 @ 箭頭函數里沒有arguments, super, new.target 三個變量, 而指向外層函數對應的值。 */ //尾調用優化 function fatorial(n) { if ( n === 1 ) { return 1; } return n * factorial(n-1); // 一般的遞歸, 保存多個調用記錄, 非常消耗內存。 } function factorial(n, total) { if ( n === 1 ) { return total; } return factorial(n-1, n * total); // 尾遞歸優化 } //蹦床函數, 將遞歸執行轉為循環執行。 function trampoline(f) { while ( f && f instanceof Function ) { f = f(); } return f; } function sum(x, y) { if (y > 0) { return sum.bind(null, x+1, y-1); } else { return x; } } trampoline(sum(1, 100000)); // 100001 //tco函數 —— 更好的尾遞歸優化實現 function tco(f) { var value; var active = false; var accumulated = []; return function accumulator() { accumulated.push(arguments); // 傳入類數組對象[x, y]且每次的值在改變。 if ( !active ) { active = true; while ( accumulated.length ) { value = f.apply(this, accumulated.shift()); /* 調用外部函數, 此時while循環繼續。 active為true, 但accumulated中參數變化。 當accumulated中的值為空時, x值value接收并返回。 */ } active = false; return value; } } } var sum = tco(function(x, y) { if ( y > 0 ) { return sum(x+1, y-1); // 相當于再次執行accumulator函數, 且傳入新的參數值。 } else { return x; } }) sum(1, 100000) // 100001 /* @ 尾遞歸實現 —— 改寫一般的遞歸函數, 確保最后一步只調用自身。 --- 尾遞歸優化 --- @ 實現意義 —— 防止棧溢出, 相對節省內存。(函數里面調用函數才叫遞歸執行, 產生前面的副作用) @ 實現要點 —— 減少調用棧, 采用循環從而替換掉遞歸。 */數組的擴展//擴展運算符 ...[1, 2, 3, 4, 5] // 1 2 3 4 5 var nodeList = document.querySelectorAll("div"); [...nodeList]; // [,,] var arr1 = [1, 2, 3]; var arr2 = [4, 5, 6]; arr1.push(...arr2) console.log(arr1) // [1, 2, 3, 4, 5, 6] let map = new Map([ [1, "one"], [2, "two"], [3, "three"] ]) let arr = [...map.keys()]; // [1, 2, 3] /* --- 用途 --- @ 將數組轉為用逗號分隔的參數序列 @ 可以展開任何含有Iterator接口的對象, 從而將其轉變為數組。 */ // Array.from() function foo() { var args = Array.from(arguments); // ... } let spans = document.querySelectorAll("span"); // ES5 let names1 = Array.prototype.map.call(spans, s => s.textContent); // ES6 let names2 = Array.from(spans, s => s.textContent); /* --- 用途 --- @ 將兩類對象轉為真正的數組。 @ 類似數組的對象 (array-like object) @ 可遍歷對象 (iterable) */ // Array.of() --- 將一組值轉換為數組 Array.of(1, 2, 3, 4, 5) // [1, 2, 3, 4, 5] // find() --- 找出數組中符合條件的第一個成員并返回該成員。 [1, 3, -8, 10].find( n => n < 0 ); // -8 // findIndex() --- 找出數組中符合條件的第一個成員并返回該成員的位置。 [1, 3, -8, 10].findIndex( n => n < 0 ); // 2 // keys() values() entries() --- 返回一個遍歷器對象, 用for...of循環遍歷。 var arr = ["a", "b"]; for ( let key of arr.keys() ) { console.log(key); } // 0 1 for ( let value of arr[Symbol.iterator]() ) { console.log(value); // Chrome, Firefox 未實現 arr.values() } // a b for ( let [key, value] of arr.entries() ) { console.log(key, value); } // 0 "a" // 1 "b" // includes() --- 表示某個數組是否包含特定的值, 返回一個布爾值。(第二個參數表示搜索的索引位置) [1, 2, 3].includes(2, 1) // true [1, 2, 3].includes(2, 2) // false 對象的擴展// Object.is() --- 比較兩個數是否嚴格相等, 比 === 符號更好。 +0 === -0 // true NaN === NaN // false Object.is(+0, -0) // false Object.is(NaN, NaN) // true // Object.assign() --- 將源對象所有可枚舉的屬性復制到目標對象。 // 屬于淺復制, 對于嵌套的對象只是復制對象的引用。 /* --- 常見用途 ---*/ // 為對象添加屬性。 class Point { constructor(x, y) { Object.assign(this, {x, y}); } } //為對象添加方法 var foo = {}; Object.assign(foo.prototype, { method1() { //... }, method2() { //... }, method3() { //... } }) // 克隆對象, 保持繼承鏈。(淺復制) function clone(obj) { var proto = Object.getPrototypeOf(obj); return Object.assign(Object.create(proto), obj); } // Object.setPrototypeOf() Object.getPrototypeOf() // 設置或獲取原型對象。 let proto = {}; let obj = { x: 10 }; Object.setPrototypeOf(obj, proto); proto.y = 20; obj.y; // 20; Object.getPrototypeOf(obj) === proto // true // Object.keys() Object.values() Object.entries() // 對可遍歷的屬性起作用, 且可以用for...of循環遍歷。 let { keys, values, entries } = Object; let obj = { a: 1, b: 2, c: 3 }; for ( let key of keys(obj) ) { console.log(key); // a b c } for ( let value of values(obj) ) { console.log(value); // 1 2 3 } for ( let [key, value] of entries(obj) ) { console.log([key, value]); // ["a", 1] ["b", 2] ["c", 3] }Set, Map數據結構// Set --- 成員值唯一的數據結構 // 數組去重 var arr = [1, 2, 3, 3, 4, 5, 5]; // 方法一 [...new Set(arr)]; // [1, 2, 3, 4, 5] // 方法二 Array.from(new Set(arr)); // [1, 2, 3, 4, 5] /* @ 具有 add(), delete(), has(), clear() 方法。 @ 包含 keys(), values(), entries(), forEach() 遍歷操作方法。 */ // Map --- 屬于鍵值對的數結構, 且與對象不同。各種類型的值都可以當作鍵。 // Map轉數組 var arr = ["a", "b", "c"]; let map = new Map( arr.map((p, i) => [i, p]) ); [...map] // [[0, "a"], [1, "b"], [2, "c"]] // Map轉對象 function mapToObj(map) { let obj = {}; for ( var [k, v] of map ) { obj[k] = v; } return obj; } // 對象轉Map function objToMap(obj) { let map = new Map(); for ( var k of Object.keys(obj) ) { map.set(k, obj[k]); } return map; } /* @ 具有 set(key, value), get(key), has(key), delete(key), clear() 方法。 @ 包含 keys(), values(), entries(), forEach() 等遍歷方法。 */ // WeakSet, WeakMap // WeakSet 實例 class Foo { constructor() { foo.add(this); } method() { if ( !foo.has(this) ) { throw new TypeError("只能在Foo的實例上使用!"); } } } // WeakMap 實例 let Element = document.querySelector(".logo"); let wm = new WeakMap(); wm.set(Element, { timesClicked: 0 }); Element.addEventListener("click", () => { var logo = wm.get("Element"); logo.timesClicked++; }); // 一旦DOM節點被刪除, 點擊一次更新的狀態就會消失。 const listener = new WeakMap(); listener.set(element, handler); element.addEventListener("click", listener.get(element), false); // 一旦DOM對象消失, 其綁定的監聽函數也會消失。 /* --- 特點 --- @ 其成員都只能是對象而且為弱引用, 即垃圾回收機制不考慮對該對象的引用。 @ 所引用的對象在外部被清除, 里面的鍵名對象和對應的鍵值對自動消失從而防止了內存泄漏。 */Iterator 和 for...of 循環/* --- Iterator --- @ 它是一種遍歷器接口, 為各種不同的數據結構提供統一的訪問機制。 --- 作用 --- @ 使數據結構的成員能夠按某種次序排序。 @ 部署了Iterator接口的數據結構可供for...of循環遍歷。 */ /* --- 原生具備Iterator接口的數據結構 --- @ Array @ Map @ Set @ String @ TypedArray @ 函數的arguments對象 @ NodeList對象 */ // 為對象添加Iterator接口 var obj = { data: ["hello", "world"], [Symbol.iterator]() { const self = this; let index = 0; return { next() { if ( index < self.data.length ) { return { value: self.data[index++], done: false } } else { return { value: undefined, done: true } } } } } } for ( var x of obj ) { console.log(x); } // hello world var itrable = obj[Symbol.iterator](); iterable.next(); // {value: "hello", done: false} iterable.next(); // {value: "world", done: false} iterable.next(); // {value: "undefined", done: true} /* --- for...of --- @ 用于遍歷鍵值, 遍歷數組時只返回具有數字索引的屬性比for...in更加可靠。 @ 用于循環遍歷部署了Symbol.iterator接口屬性的數據結構。 */ let arr = [3, 5, 7]; arr.foo = "hello"; for (let i in arr) { console.log(i) // "0", "1", "2", "foo" } for (let i of arr) { console.log(i) // "3", "5", "7" }參考書籍 : 《 ES6標準入門 》( 阮一峰 )
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/93741.html
相關文章
2017-08-08 前端日報
摘要:前端日報精選一行代碼的逆向工程譯只需四個步驟使用實現頁面過渡動畫如何實現一個基于的模板引擎解剖組件的多種寫法與演進深入理解筆記擴展對象的功能性中文基礎系列一之實現抽獎刮刮卡橡皮擦掘金小游戲個人文章和最常用的特征眾成翻譯常用語法總 2017-08-08 前端日報 精選 一行 JavaScript 代碼的逆向工程【譯】只需四個步驟:使用 React 實現頁面過渡動畫如何實現一個基于 DOM...
前端學習路線
摘要:具體來說,包管理器就是可以通過命令行,幫助你把外部庫和插件放到你的項目里面并在之后進行版本升級,這樣就不用手工復制和更新庫?,F在有的包管理器主要是和。 一、基礎 1、學習HTML基礎 HTML給你的網頁賦予了結構。它就像是人的骨架那樣讓你保持站立。首先你需要去學習語法以及它必須提供的一切。你的學習應該聚焦在下面這些東西上: 學習HTML基礎,了解如何編寫語義HTML 理解如何把網頁分...
慕課網js面試題學習筆記(ES6 標準) ——實時更新
摘要:而第一種方法只能判斷引用類型,不能判斷值類型,因為值類型沒有對應的構造函數描述一個對象的過程生成一個新的空對象指向這個新對象執行構造函數中的代碼,即對賦值將新對象的屬性指向構造函數的屬性返回,即得到新對象。 最近在在看前端面試教程,這篇文章里大部分是看視頻的過程中自己遇到的不清楚的知識點,內容很簡單,只是起到一個梳理作用。有些地方也根據自己的理解在作者的基礎上加了點東西,如有錯誤,歡迎...
發表評論
0條評論
church
男|高級講師
TA的文章
閱讀更多
穩愛云:香港CN2 GIA,2核/2G/20M帶寬,月付34元,美國CERA聯通首月半價25元,簡單
閱讀 3409·2021-10-11 11:06
Making An Indicator With Pure CSS
閱讀 2191·2019-08-29 11:10
[譯] 究竟什么是DOM?!
閱讀 1952·2019-08-26 18:18
mac 下安裝Nginx 和 反向代理
閱讀 3260·2019-08-26 13:34
Promise 對象的理解
閱讀 1565·2019-08-23 16:45
js秒數轉換時分秒(hh:mm:ss)
閱讀 1044·2019-08-23 16:29
用Vue開發仿旅游站webapp項目總結 (上)
閱讀 2804·2019-08-23 13:11
PDF.js實現個性化PDF渲染(文本復制)
閱讀 3233·2019-08-23 12:58