溫故而知新,能夠爲師矣. 相信你們都會有這種感受,不少學過的知識常常不使用就會慢慢遺忘!!!本文把之前本身關於 ES6的入門讀書筆記從新彙總了一下,並結合了工做中經常使用的使用場景...python
ES5中聲明變量: a. var命令會發生」變量提高「現象,即變量能夠在聲明以前使用,值爲undefined。 b. es5中變量只有兩種做用域: 全局 和 局部(函數內聲明); 全局和局部都有變量提高現象;先提早,再進行賦值. 不合理場景1: 局部內層變量 可能覆蓋掉 全局變量 不合理場景2: for循環中 用var聲明的 變量i; 會泄露成全局變量,循環結束並無消失 ES6中聲明變量: 1.聲明的變量a的做用域爲塊級,而且只在本身所在的塊級做用域起做用; 外層做用域不能訪問內層, 內層能夠訪問外層的; 2.內&&外層的同名變量互不干擾; 內層從新賦值也不會對外層形成影響; 3.變量必須先聲明,再使用,不然報錯...(暫時性死區特性), 沒有所謂的變量提高 4.同一做用域不能重複聲明同一個變量; 函數function第一層做用域變量聲明不能和形參同樣; 不然報錯 //注意: 1. es6中,變量在for循環中的使用 每一輪的i值 只在當前的循環中有效; 至關於每一次循環i都是一個新變量 // 1.循環變量在設置的時候是: 一個父做用域 // 2.循環體內部又是一個單獨的子做用域 // 3.因此當同時兩個塊級做用域如使用相同的變量i,循環體內部會使用本身做用域聲明的i 2.ES6 規定,塊級做用域之中,函數聲明語句的行爲相似於let,在塊級做用域以外不可引用。 // 1.避免在塊級做用域內使用函數時聲明的方式(function fn(){xxx})聲明函數 // 2.可使用表達式方式 let f = function(){} // 也就是外層沒法調用內層聲明的函數... 3.const聲明一個常量: 該變量不能變化,是一個恆定值 const NUM_100 = 100; // 定義時就須要初始化 // const實際上保證的並非變量的值不得改動,而是變量指向的那個內存地址所保存的數據不得改動。 // 值類型: 數據就 等同於 這個常量的地址的值 // 引用類型: 這個常量 是一直指向一個固定的地址, 不能變的(修改指向就保錯,即賦值操做); 只不過對象自己可變
解構賦值,我按照字面意思就是 解析數據結構, 而後給一一對應的變量進行賦值的一種語法es6
解構的語法:編程
=號左邊是: 匹配模式; =號右邊是: 實際的數據(或者數據對應的變量); 解構的結果: 解構成功: 左邊變量的值 就是右邊對應變量的值 解構不成功: 即沒有對應值匹配, 變量的值變爲undefined 不徹底解構: 左邊的模式之匹配到右邊數組的一部分
變量是複雜數據類型(數組,對象)json
1.數組解構賦值 1.右邊的值須要可以被遍歷 2.容許左邊給默認值: let [x=1, y=x] = ['xxxx']; 3.支持嵌套結構的 解構賦值 注意: let [x, y=true] = ['xxxx']; // 右邊數組對應成員要 === undefined // console.log(x,y); // 若是是null, 則默認值不會生效; // 若是右邊 不是undefined, 則左邊 會取到值 2.對象的解構賦值 1.對象自己就是無序的, 是根據左右同名變量 來作賦值操做,匹配規則和數組相似 // 對象的解構賦值的內部機制,是先找到同名屬性,而後再賦給對應的變量。真正被賦值的是後者 例: let { foo: foo, bar: bar } = { foo: "aaa", bar: "bbb" }; 2.持嵌套結構的 解構賦值 let obj = {}; let arr = []; ({foo: obj.num, bool: arr[0]} = {foo: 123, bool: true}); // 圓括號 console.log(obj, arr); 3.對象的解構賦值,能夠很方便地將現有對象的方法,賦值到某個變量,幾個例子 3-1 let {sin, cos} = Math; // 將math對象中方法給對象 3-2 取出數組的首尾2項 let list = [1,2,323,123,12,2]; let {0: first, [list.length-1]: last} = list;
變量是簡單數據類型(字符串,數值,布爾值)數組
1.字符串的解構賦值 字符串被轉換成了一個相似數組的對象: 能夠理解未僞數組 let [a,b,c,d,e] = 'hello'; // 每一個變量對應一個字符 2.數值和布爾值的解構賦值 解構賦值的規則: 只要等號右邊的值不是對象或數組,就先將其轉爲對象。 因爲undefined 和 null沒法轉爲對象,因此對它們進行解構賦值,都會報錯 因此, 數值和布爾值會先轉成其包裝對象Number 和 Boolean對象;而後能夠賦值對象的屬性
函數參數的解構緩存
1.會將實參與形參一一對應 console.log([[1, 2], [3, 4]].map(([a, b]) => a + b));
經常使用的使用場景babel
變量之間值的交換; 函數中傳參和接受返回值(對象的方式); 對象遍歷等等... 1.交換變量的值 let v100 = 100; let v1 = 1; [v1, v100] = [v100, v1]; console.log(v1, v100); 2.接受函數的多個返回值: 好比數組,對象 // 函數只能返回一個值,若是要返回多個值,只能將它們放在數組或對象裏返回。 // 有了解構賦值,取出這些值就很是方便。 function example() { return [1, 2, 3]; } // let [a, b, c] = example(); 3.函數傳參 // 解構賦值能夠方便地將一組參數與變量名對應起來 // 參數是一組有次序的值 function f([x, y, z]) { } f([1, 2, 3]); // 參數是一組無次序的值 function f({x, y, z}) { } f({z: 3, y: 2, x: 1}); 4.json數據的處理 // 解構賦值對提取 JSON 對象中的數據,尤爲有用。 let jsonData = { id: 42, status: "OK", data: [867, 5309] }; let {id, status, data: arr1} = jsonData; console.log(id, status, arr1); 5.設置函數參數的默認值 // 避免了在函數體內部再寫var foo = config.foo || 'default foo'; // 在傳參時; 特別是傳一個對象參數時, 能夠事先配置好參數的默認值 // func({參數1 = true, 參數2 = false, ...} = {外部實參沒有傳值的就是用默認值}){} 6.遍歷 Map 結構 // 可迭代對象, 均可以用for...of 來遍歷 const map = new Map(); map.set('first', 'hello'); map.set('second', 'world'); for (let [key, value] of map) { console.log(key + " is " + value); } // 獲取鍵名 for (let [key] of map) { console.log(key); } // 獲取鍵值 for (let [,value] of map) { console.log(value); } 7.模塊導入 // 加載模塊時,每每須要指定輸入哪些方法。解構賦值使得輸入語句很是清晰 // const { SourceMapConsumer, SourceNode } = require("source-map");
1. 處理4個字節存儲的單個字符 // 測試一個字符由兩個字節仍是由四個字節組成的最簡單方法 (Unicode 編號大於0xFFFF) // codePointAt(下標): 返回10機制字節碼; function is_32bit(char) { return char.codePointAt(0) > 0xFFFF; } console.log(is_32bit('𠮷a')); // true // 識別4個字節(32位)組成的單個字符 console.log(String.fromCodePoint(0x20BB7)); // 𠮷 2.字符串的遍歷for of let text = '個人名字'; for (const char of text) { console.log(char); } 3.肯定一個字符串中是否包含另外一個目標字符串 // includes(), startsWith(), endsWith() // 返回true和false console.log(text.startsWith('我')); console.log(text.endsWith('我')); console.log(text.includes('我')); 4.repeat(num); 將字符串重複num次並返回 console.log(text.repeat(3)); 5.字符串補全長度的功能 // padStart()用於頭部補全,padEnd()用於尾部補全 // 參數1: 補全後的生效長度; 參數2: 用於補全的字符串(沒有參數默認空格) // 長度過了; 會截取超出位數的字符串 // 長度 <= 原長度; 返回本身 // 用途1: 將數值補全爲指定位數 console.log("1".padStart(10, '0')); // 0000000001 // 場景2: 日期補全 console.log('09-12'.padStart(10, '2018-MM-DD')); // 2018-09-12
模板字符串: 反引號 ` 標識; // 變量名使用 ${變量名}; 能夠省去字符串的拼接了 let name = "bob"; let age = 24; console.log(`Hello ${name}, how are you ${age}?`); // ${這裏面能夠進行運算; 函數調用; 放對象的屬性等}; 至關於執行js代碼 // 還能夠相互嵌套 固然,模板字符串的用法比較複雜,後續再深刻總結
// 1.檢查數字爲有限值 Number.isFinite(12); // true; 其餘類型都爲false // 2.檢查數值是否是NAN Number.isNaN(1+NaN); // true; NaN 數值與非數值運算的結果NaN // 3.Number.parseFloat 和 Number.parseInt; 將ES5的全局方法移到Number對象上 // 4.Number.EPSILON * Math.pow(2, 2): 兩個浮點數之間的最小偏差; // 差值小於它, 就能夠認爲時相等 // 5.Math方法的擴展 console.log(Math.round(4.5)); // 5; 四捨五入 // Math.trunc方法用於去除一個數(正負均可以)的小數部分,返回整數部分。 console.log(Math.trunc(3.1)); // 兼容性寫法 // Math.trunc = Math.trunc || function(x) { // return x < 0 ? Math.ceil(x) : Math.floor(x); // }; // Math.sign() // 判斷正負, 仍是0; 對非數值,能轉化的轉化; 不能轉的就是NaN // 返回值: 正 +1; 負 -1; 0; -0; 其餘值 NaN
ES6中會將數組空位轉爲undefined數據結構
1.Array.from(param1, param2)方法用於將兩類對象轉爲真正的數組: 參數1: 一個對象 ==> 僞數組對象和可遍歷(iterable)的對象 參數2: 回調函數 ==> 相似於數組的map方法,對每一個元素進行處理,將處理後的值放入返回的數組。 return值: 一個數組; 示例: let arrayLike = { '0': 'a', '1': 'b', '2': 'c', length: 3 // 0: 'a', // 1: 'b', // 2: 'c', // length: 3 }; let real_arr = Array.from(arrayLike); 2.Array.of(傳一組數值); 用於將一組值,轉換爲數組。彌補了構造函數Array()傳數值的缺點 參數: 一組數值,如: 1,2,3,4... return值: 一個數組 3.實例方法 3.1 arr.find(): 相似過濾函數filter(function(value, index, arr)) 使用: 傳入一個回調函數, 返回第一個符合要求的成員 示例: var res = [1,2,3,4,-100].find( n => n < 0 ); // -100 3.2 arr.findIndex(): 同上,只不過是返回第一個符合條件的數組成員的位置 注意: 第二個參數是傳一個對象,回調函數中若使用了 this, 則指向這個對象 3.3 arr.includes(): 判斷數組中是否包含咱們給定的值;這樣之後就不用indexOf了 3.4 實例數組的遍歷方法: entries(),keys() 和 values() 用於遍歷數組 返回一個遍歷器對象 // keys()是對鍵名的遍歷: 對應索引 // values()是對鍵值的遍歷: 對應值 // entries()是對鍵值對的遍歷: 索引+值 4.數組擴展方法 [a, b, c] map映射, reduce彙總, filter過濾, forEach迭代 1. map: 一個映射一個 // [100, 59, 22] => [及格, 不及格, 不及格] let score = [100, 59, 22]; let res = score.map( item => item>60? '及格':'不及格' );console.log(res); 2. reduce: 一堆變成一個 // temp爲中間結果; 若是不設置,則爲第一個下標爲0的數 let res1 = score.reduce(function(temp, item, index, arr) { if (index != arr.length - 1) { return item + temp; } else { return (temp + item) / arr.length; } }); console.log(res1); 3.filter: 保留我想要的結果 let res2 = score.filter( item => item%11!=0); console.log(res2); 4.forEach: 只是操做一下每一項; 返回值爲undefined let arr = [1,2,3,4] arr.forEach(function (item, index, arr) { // 這裏能夠用外部變量接受 這裏面操做的值 console.log(index +':'+ item); }); console.log(res3); // undefined
這裏主要介紹一下對象的多種遍歷方法;其餘內容在擴展運算符...中總結.app
1.for...in for...in循環遍歷對象自身的和繼承的可枚舉屬性(不含 Symbol 屬性)。 2.Object.keys(obj),values(obj),entries(obj) 返回一個數組,包括對象自身的(不含繼承的)全部可枚舉屬性(不含 Symbol 屬性)的鍵名,值,鍵值對。 3.Object.getOwnPropertyNames(obj) 返回一個數組,包含對象自身的全部屬性(不含 Symbol 屬性,可是包括不可枚舉屬性)的鍵名。 4.Object.getOwnPropertySymbols(obj) 返回一個數組,包含對象自身的全部 Symbol 屬性的鍵名。 5.Reflect.ownKeys(obj) 返回一個數組,包含對象自身的全部鍵名,無論鍵名是 Symbol 或字符串,也無論是否可枚舉。
1.擴展運算符是什麼? 擴展運算符用三個點...表示: 至關於函數rest參數的逆運算, 能夠將數組,對象中的成員序列化出來 我這裏暫且把它理解爲一種運算符吧, 用來解析各類數據類型的成員 2.擴展運算符的使用場景? 2.1 將數組成員轉爲一個逗號分隔的參數序列: 這樣調用一些數組的API時; 能夠直接傳一個...arr進去,省去了傳參的麻煩 例1: console.log(...[1,2,3]); // 1 2 3 例2: var date = new Date(...[2015, 01, 01]); console.log(date); // 2015-01-31T16:00:00.000Z 2.2 取代apply方法: // ES5 的寫法 let max1 = Math.max.apply(null, [14, 3, 77]); // ES6 的寫法 let max2 = Math.max(...[14, 3, 77]); 2.3 數組的深拷貝: 將對象所有拷貝一份,是一個獨立的內存空間 let arr1 = [0, 1], arr2 = [...arr1]; // 用變量去接受通過擴展運算符運算的數組 arr1[0] = 100; // 修改數組arr1 console.log(arr1); // [ 100, 1 ] 發送改變 console.log(arr2); // [ 0, 1 ] 未改變 2.4 數組的合併 注意: 合併操做是淺拷貝: 是對數組中對象成員的引用 淺拷貝: (分爲簡單數據類型引用: 修改數據另外一個不會變; 複雜數據類型引用: 修改後會改變) arr3 = [...arr1, ...arr2]; // 此時arr3 爲一個新數組; [ 100, 1, 0, 1 ],由於內部成員都是數值, 因此修改了arr1或者arr2中的元素也不會變 那麼,若是數組中成員是對象; 則會改變成員屬性,合併生成的數組成員也會變 const a1 = [{ foo: 1 }]; const a2 = [{ bar: 2 }]; const a3 = [...a1, ...a2]; console.log(a3); // [ { foo: 1 }, { bar: 2 } ] a1[0].foo = 100; console.log(a3); // [ { foo: 100 }, { bar: 2 } ] 2.5 能夠和變量的解構賦值一塊兒使用; 右邊是對象也是能夠的 let [first, second, ...rest] = [1,2,3,4,5,6]; console.log(first); // 1 console.log(second); // 2 console.log(rest); // [3,4,5,6] 2.6 還有與Array.from()方法相似的做用, 將 相似數組的對象和可迭代對象 轉爲真數組 console.log([...'hello']); // [ "h", "e", "l", "l", "o" ] 注意: 若是涉及到操做四個字節的 Unicode 字符的函數; 可使用[...string], ...可以識別; 2.7 擴展運算符在對象中的使用 // 解構賦值, 若是右邊數據是undefined或null 則解構會失敗 let { x, y, ...z } = { x: 1, y: 2, a: 3, b: 4 }; // x,1; y,2; z,{a:3, b:4} // 注意: 若是擴展運算符後面不是對象,則會自動將其轉爲對象。 {...1}, {...true}, {...undefined}, {...null} 都會轉爲 空對象{}
語法: function(x=默認值x, y=默認值y); 固然也可使用解構賦值,使用對象的形式設置,({x=xxx, y=yyy}) 默認值參數放在括號尾部 1. ES5中設置默認值的方式 function fn1(x, y) { y = y || "world"; // ES5中,在函數體內賦值一個默認值 console.log(x, y); } fn1('hello'); // hello world fn1('hello', 'bob'); // hello bob fn1('hello', ''); // 傳空值時也使用默認值 fn1('hello', false); // 傳false時也使用默認值 // ES6中 直接給()中參數賦默認值, 至關於初始化形參, 函數體內不容許let和const再次聲明 // ES6中會事先對參數y進行類型判斷: typeof y === 'undefined'; 是纔給默認值 function fn2(x, y = 'ES6') { console.log(x, y); } fn2('learning'); //learning ES6 fn2('learning', ''); //learning 空也能輸出 fn2('learning', false); //learning false 布爾值也能夠 2. 構造函數中用來初始化 函數的屬性function Person(name='bob') {this.name = name}; 也是能夠直接在()中傳默認值的 3.解構賦值形式給函數傳參 例1: function fn3({x, y = 100}) { // 函數的形參接受一個對象; 函數傳值也要傳一個對象; console.log(x, y); }; // ES5中咱們是傳一個對象,而後再定義變量 保存 對象中對應的屬性值 // ES6能夠直接在形參中 去接受對應的屬性值 fn3({}); // undefined 100; fn3(); // 保錯 例2: // 下面咱們重寫一下, 注意:::這種方式的傳參是設置了對象解構賦值的默認值爲空對象,這樣直接調用便不會報錯 function fn4 ({x, y = 101} = {}) { // 不傳值的狀況下: 給函數一個默認參數: 空對象 console.log(x, y); }; fn4(); //undefined 101; 至關於 fn4({}); 4.默認參數的做用域 函數()中式一個單獨的做用域, ES6中函數體中的運算會先去()中找對應的變量進行運算
ES6 引入 rest 參數(形式爲...變量名),用於獲取函數的多餘參數,這樣就不須要使用arguments對象了。 rest 參數搭配的變量是一個數組,參數都放在這個數組中。要使用的話,直接在函數體中遍歷便可,固然...rest放在()尾部 舉個栗子: function add (...number) { let sum = 0; // number變量至關於一個存放形參的數組 // 可使用數組的方法,也就是說,咱們能夠看成數組來操做這個參數number // 基本方法 和 迭代方法都能使用 for (let num of number) { sum += num; } return sum; } console.log(add(1,2,3,4,5)); // 15
1.箭頭函數基本語法: var 變量指向這個函數 = (參數1,參數2...) => {函數體大於一行時用大括號} 理解: ES6中箭頭函數 至關於函數的簡寫,省略了function關鍵字,只有一個參數時還能夠省略() 箭頭左邊是 (參數) => 箭頭右邊是函數體(一行代碼能夠省略大括號,直接寫返回值表達式) //若是返回的是一個對象則加括號({對象}) 2.經常使用的使用場景 2.1 回調函數的簡化 // 好比數組經常使用的迭代方法map: 常規方法是 傳入一個回調函數 function(x) {return x**2}; var arr1 = [1,2,5,3,6,0]; var result1 = arr1.map(x => x**2); // 排序 var result2 = arr1.sort((a, b) => a - b); // [0,1,2,3,5,6] // 箭頭函數傳rest參數 let arr3 = (...numbers) => numbers; // 自動將參數序列轉爲數組 2.2 嵌套使用; 函數式編程 例如:要實現將一個值 插入到數組 某個值的後面, 而後返回一個新數組 function insert (value) { return {into: function (array) { return {after: function (after_value) { // 起始位, 要刪除的項, 替換項 array.splice(array.indexOf(after_value) + 1, 0, value); return array; }} }} } // 用箭頭函數實現; 簡化了不少 // 聲明一個變量指向函數; 不要忘記對象用()包起來 var insert = (value) => ({into: (array) => ({after: (after_value) => { array.splice(array.indexOf(after_value) + 1, 0, value); return array; }})}); var res = insert(100).into([1, 2, 3]).after(2); console.log(res); // [ 1, 2, 100, 3 ] 3.箭頭函數注意事項; 1.this對象 ==> 指向定義時的對象, 而不是誰調用就指向誰了; 至關於固定了this指向 箭頭函數根本沒有本身的this,致使內部的this就是外層代碼塊的this 箭頭函數中的this 至關於ES5中 引用了外層函數的this; 在外層函數用var _this = this; 而後在箭頭函數中使用 2.箭頭函數不能看成構造函數,不能使用new去聲明 3.沒有arguments對象了, 使用rest參數替代 4.不能使用yield, 不能夠做爲生成器函數
函數的尾調用優化 function f(x){ return g(x); // 函數f的最後一步是 調用函數g,這就叫尾調用。 } function f(x){ g(x); // 函數沒有明確返回值, 默認回返回undefined; 因此不是尾調用 return undefined; } 優化思路: 用內層函數的調用幀,取代外層函數的調用幀(保存了函數調用後的信息) 至關於能夠不用調用外層函數 注意: 只有再也不用到外層函數的內部變量,內層函數的調用幀纔會取代外層函數的調用幀, 不然就沒法進行「尾調用優化」。 尾遞歸優化 思路: 把全部用到的內部變量改寫成函數的參數 1.參數設置成默認值的方式; 2.函數柯里化currying;意思是將多參數的函數轉換成單參數的形式 function Fibonacci (n , ac1 = 1 , ac2 = 1) { if( n <= 1 ) {return ac2}; // 尾部調用自身; 而且參數中保存了上一次調用幀; 節省內存 return Fibonacci (n - 1, ac2, ac1 + ac2); } console.log(Fibonacci(100)); // 注意: // ES6 的尾調用優化只在嚴格模式下開啓,正常模式是無效的。
Set數據結構: 能夠理解爲沒有重複成員的一個相似數組的對象; 就叫集合吧
結構形式: {1, 2, 3, 4}
使用方法:
// 使用構造函數Set; 參數爲一個可遍歷的對象
const set = new Set([1,2,3,4]); // 實例化一個set; set結構是可迭代的對象
// 返滬值: {1, 2, 3, 4}模塊化
Set的屬性和方法
1. size: 返回set集合的大小, 即成員個數 2. Set的增刪查 // add(value):添加某個值,返回 Set 結構自己。 // delete(value):刪除某個值,返回一個布爾值,表示刪除是否成功。 // has(value):返回一個布爾值,表示該值是否爲Set的成員。 // clear():清除全部成員,沒有返回值。 3. Set遍歷成員; Set的遍歷順序就是插入順序。 // keys():返回鍵名的遍歷器 // values():返回鍵值的遍歷器 // entries():返回鍵值對的遍歷器 // forEach():使用回調函數遍歷每一個成員, 回調參數爲鍵值和set自身
使用場景:
Set做爲一種數據結構,主要用來存放數據,而且內部成員不重複; 咱們能夠利用它的這個特性來作一些事. 1.好比去重 let arr = [1,2,2,3,1,1,14]; let str = 'dsadaedwdwa'; console.log([...new Set(arr)]); console.log([...new Set(str)].join());
其實Map有點相似 python中的字典結構;
ES6中Map相似於對象,也是鍵值對的集合,可是「鍵」的範圍不限於字符串,各類類型的值(包括對象)均可以看成鍵。
也就是說,Object 結構提供了「字符串: 值」的對應,Map 結構提供了「值 => 值」的對應
結構形式: Map: { [ 1, 2, 3 ] => '數組', 'name' => { name: 'bob' } }
使用方法:
使用構造函數Map 進行實例化; 參數爲雙元素的可迭代對象(可以調用next方法的對象)
const newMap = new Map([['name', 'Blob'], ['age', 24]]); // 也可實例化一個空map對象,經過set(值1, 值2)方法去添加成員
Map的屬性和方法: 基本與上面的Set一致
1.Map的增刪查 // set(key1, value1):添加一個鍵值對 // get(key); 獲取某個鍵值對 // delete(key):刪除某個鍵值對 // has(key):返回一個布爾值,表示該值是否爲Map的成員。 // clear():清除全部成員,沒有返回值。
經常使用場景:
可使用擴展運算符...Map 能夠實現與數組,對象,json對象的互轉; 咱們定義固定格式的數據時可使用, 也能夠用來簡化判斷語句 # set 中來判斷 code const NEED_LOGIN_CODE_SET = new Set([10007,100011]) if (NEED_LOGIN_CODE_SET.has(code)) { } # map 取值 let buildEnv = process.env.VUE_APP_ENV const K_V = [ ['development', 'address1'], ['test', 'address2'], ['production', 'address3'] ] const URL_MAP = new Map(K_V) export default URL_MAP.get(buildEnv)
for...of是ES6新增的語法;用來遍歷具備Iterator 接口的對象; 這種對象有next()方法,\
能夠對自身進行遍歷,每一次調用便返回對應的值...
for...of循環可使用的範圍包括數組、Set 和 Map 結構、某些相似數組的對象(好比arguments對象、DOM NodeList 對象)、Generator 對象,以及字符串。
ES5中的類實現
// ES5中對象實例化的方法: 經過構造函數實例化
function Func(x, y) { this.x = x; this.y = y; } // 給構造函數的原型添加屬性 Func.prototype.toString = function() { // 把對象轉爲字符串 return '(' + this.x + ',' + this.y + ')'; } // 實例化一個對象 var f = new Func(1,100); console.log(f.toString());
ES6的類實現
// ES6中 通class來定義類; 其實就是構造函數的改寫,是js的語法更像後臺語言 class Func1 { // 構造實例對象的方法; 至關於初始化 constructor(x, y) { this.x = x; this.y = y; } // 添加類方法: toString()方法 toString() { return '(' + this.x + ',' + this.y + ')'; } } // 類: 就是一個函數, 自己爲一個構造函數; 也是經過new來實例化一個對象 console.log(typeof Func1); console.log(Func1 === Func1.prototype.constructor); let f1 = new Func1(); console.log(f1.__proto__.constructor); // 省略了__proto__ // 類的方法都定義在prototype對象上
ES6中的繼承
// ES6面向對象寫法: class 替換 構造函數 class User { // 構造器, 初始化 constructor(name, pass) { this.name = name; this.pass = pass; } // 添加方法和屬性 showName() { console.log(this.name); } showPass() { console.log(this.pass); } } // 在繼承 和 封裝上的優點; 擴展性強...; 不用從0開始;; 可使用前人造好的輪子 // 繼承超類的屬性和方法 class VipUser extends User { // 子類的初始化 constructor(level, ...args) { // 至關於調用父類的constructor(name, pass) super(...args); // super做爲函數調用時,表明父類的構造函數 // super做爲對象時,在普通方法中,指向父類的原型對象;在靜態方法中,指向父類。 this.level = level; } // 方法 showLevel() { console.log(this.level); } } let vip = new VipUser(77, 'huhua', '123'); // 實例化 vip.showLevel(); vip.showName(); vip.showPass(); // 面向對象中類的應用實例 // 好比一個組件: 就是一個 class 繼承一個組件 // JSX: == babel; browser.js
// 1.JSON對象: 兩個方法 let json = {"name": '哈哈', "sex": "女"}; // json對象鍵值必須是雙引號 let str1 = 'http://www.baidu.com?data=' + encodeURIComponent(JSON.stringify(json)) ; // JSON對象轉爲json字符串 console.log(str1); let str2 = JSON.parse('{"a": 12, "b": "hello world"}'); console.log(str2); // JSON字符串 轉爲 對象 console.log(str2.a); // 2.JSON簡寫 // 簡寫: 若是key值和value是同樣的; 直接寫一個就能夠了... // 能夠省略一個funcion; 即 success: function(obj) {} ==> 能夠寫成 success(obj){}
這裏說兩種經常使用的模塊加載方式
- commonJS模塊 CommonJS 模塊就是對象,輸入時必須查找對象屬性 導出: module.exports = { m1: 'xxx', m2: function(){}} 導入: const { m1, m2 } = require('模塊名') 模塊輸出的是一個值的拷貝: 若是輸出一個值,模塊內部的變化就影響不到這個值 模塊是運行時加載(整個對象所有加載) - ES6模塊化 export導出模塊: 默認導出:export default Person(導入時可任意命名) 單獨導出:export const name = 'xxoo' 按需導出:export { age, name, sex } 前提是得先定義好 更名導出:export { name as newName } import導入模塊: 默認導入:import Person from "person" 總體導入:import * as Person from "person" 按需導入:import { age, name, sex } from "person" 更名導入:import { name as newName } from "person" 自執行導入:import "person" 複合導入:import Person, { name } from "person" ES6 模塊是編譯時輸出接口(按需導入) ES6 模塊輸出的是值的引用, 即動態引用,而且不會緩存值,模塊裏面的變量綁定其所在的模塊 若是原始模塊的變量變化,就會影響引入了這個變量的模塊中的值
未完待續...