前言
溫故而知新,可以爲師矣. 相信大家都會有這種感覺,很多學過的知識經常不使用就會慢慢遺忘!!!本文把以前自己關於 ES6的入門讀書筆記重新彙總了一下,並結合了工作中常用的使用場景...
變量聲明方式 let,const
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實際上保證的並不是變量的值不得改動,而是變量指向的那個內存地址所保存的數據不得改動。
// 值類型: 數據就 等同於 這個常量的地址的值
// 引用類型: 這個常量 是一直指向一個固定的地址, 不能變的(修改指向就保錯,即賦值操作); 只不過對象本身可變
變量的解構賦值語法
解構賦值,我按照字面意思就是 解析數據結構, 然後給一一對應的變量進行賦值的一種語法
-
解構的語法:
=號左邊是: 匹配模式; =號右邊是: 實際的數據(或者數據對應的變量); 解構的結果: 解構成功: 左邊變量的值 就是右邊對應變量的值 解構不成功: 即沒有對應值匹配, 變量的值變爲undefined 不完全解構: 左邊的模式之匹配到右邊數組的一部分
-
變量是複雜數據類型(數組,對象)
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));
-
常用的使用場景
變量之間值的交換; 函數中傳參和接受返回值(對象的方式); 對象遍歷等等... 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
對象的擴展
這裏主要介紹一下對象的多種遍歷方法;其他內容在擴展運算符...中總結.
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中函數體中的運算會先去()中找對應的變量進行運算
rest參數
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 和 Map 數據結構
set
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
其實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
for...of是ES6新增的語法;用來遍歷具有Iterator 接口的對象; 這種對象有next()方法,\
可以對自身進行遍歷,每一次調用便返回對應的值...
for...of循環可以使用的範圍包括數組、Set 和 Map 結構、某些類似數組的對象(比如arguments對象、DOM NodeList 對象)、Generator 對象,以及字符串。
class關鍵字: 類
-
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
json簡寫模式
// 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 模塊輸出的是值的引用, 即動態引用,並且不會緩存值,模塊裏面的變量綁定其所在的模塊
如果原始模塊的變量變化,就會影響引入了這個變量的模塊中的值
未完待續...