摘要:函數調用會在內存形成一個調用記錄,又稱調用幀,保存調用位置和內部變量等信息。等到運行結束,將結果返回到,的調用幀才會消失。方法用于將一組值,轉換為數組。,和遍歷數組方法返回一個布爾值,表示某個數組是否包含給定的值,與字符串的方法類似。
ES6 簡介
ES6, 全稱 ECMAScript 6.0 ,是 JavaScript 的下一個版本標準,2015.06 發版。
let 和 const let 命令let 命令,用來聲明變量。它的用法類似于 var,區別在于 var 聲明的變量全局有效,let 聲明的變量只在它所在的代碼塊內有效。
// 變量i儲存的值是10,所以執行a[2]()后輸出10 var a = []; for (var i = 0; i < 10; i++) { a[i] = function () { console.log(i); }; } a[2](); // 10 // 修正方法 // 閉包會使得函數中的變量都被保存在內存中,所以執行a[2]()后輸出2 var a = []; for (var i = 0; i < 10; i++) { (function (i) { a[i] = function () { console.log(i) } })(i); } a[2](); // 2 // es6 // let聲明的i只在當前的代碼塊有效,所以每次for循環相當于用let重新聲明一次i var a = []; for (let i = 0; i < 10; i++) { a[i] = function () { console.log(i); }; } a[2](); // 2 // 注:JavaScript 引擎內部會記住上一輪循環的值,初始化本輪的變量i時,就在上一輪循環的基礎上進行計算。
let 不存在變量提升,必須先聲明后使用,否則報錯;var 存在變量提升,未聲明前使用輸出 undefined。
let 存在暫時性死區,在代碼塊內,使用 let 命令聲明變量之前,該變量都是不可用的。
let 不允許重復聲明。
const 命令const 聲明一個只讀的常量。一旦聲明,常量的值就不能改變。不能只聲明不賦值。
const a = 10; a = 20; // 報錯 const b; // 報錯
const 的作用域與 let 相同。
if(true) { const num = 5; } console.log(num); // 報錯
const 聲明對象,常量對象內存地址,因此對象本身可改,但是給常量重新賦值就會報錯。
const obj = {}; obj.a = "a"; obj = {}; // 報錯塊級作用域和函數作用域
ES5 規定,函數只能在頂層作用域和函數作用域之中聲明,不能在塊級作用域聲明。但是在 ES6 中,函數可以在塊級作用域中聲明。但是,市面上很多瀏覽器都不支持 ES6,所以應該避免在塊級作用與中聲明函數。
ES6 聲明變量的方法var
function
let
const
import
class
變量的解構賦值ES6 允許按照一定模式,從數組和對象中提取值,對變量進行賦值,這被稱為解構(Destructuring)。
數組的解構賦值模式匹配賦值,如果解構不成功,變量的值就等于 undefined。
let [a, [[b], c]] = [1, [[2], 3]]; console.log(a,b,c); // 1, 2, 3 let [x, , y, z] = [1, 2, 3]; console.log(x); // 1 console.log(y); // 3 console.log(z); // undefined
不完全解構賦值,等號左邊的模式,只匹配一部分的等號右邊的數組。
let [x, [y], z] = [1, [2, 3], 4]; console.log(x); // 1 console.log(y); // 2 console.log(z); // 4
數組結構賦值右邊必須是數組,模式不匹配則報錯。
let [a] = {}; // 報錯
解構賦值可以添加默認值,并且可以引用解構賦值的其他變量。
let [a = 1, b = 2] = [, 3]; console.log(a); // 1 console.log(b); // 3 let [x = 1, y = x] = []; // x = 1; y = 1 let [x = 1, y = x] = [2]; // x = 1; y = 2
數組解構賦值可用于交換變量的值。
let [a, b] = [1, 2]; console.log(a, b); // 1, 2 [b, a] = [a, b]; console.log(a, b); // 2, 1對象的解構賦值
變量必須與屬性同名
let { a, b, c } = { a: "aaa", b: "bbb" }; console.log(a); // "aaa" console.log(b); // "bbb" console.log(c); // undefined
變量名與屬性名不一致
let { a: x, b: y } = { a: "aaa", b: "bbb" }; console.log(x); // "aaa" console.log(y); // "bbb"
嵌套賦值,如果子對象所在的父屬性不存在,會報錯,慎用。
let { a, a: {x}, b: y } = { a: {x: "xxx",y: "yyy"}, b: "bbb" }; console.log(a); // { x: "xxx", y: "yyy" } console.log(x); // "xxx" let {c: {d: {e}}} = {c: "ccc"}; // 報錯 console.log(e)
變量解構賦值也和數組的解構賦值一樣,可以賦默認值,變量解構賦值時,不能將大括號寫在行首,否者 JavaScript 引擎將會按代碼塊執行。
let x; {x} = {x: 1}; // 報錯 // 正確寫法 let x; ({x} = {x: 1});字符串解構賦值
字符串解構賦值,將字符串轉化成數組對象
const [a,b,c] = "123456789"; const {length} = "123456789"; console.log(a, b, c, length); // 1, 2, 3, 9函數解構賦值
const arr = [[1, 2], [3, 4]].map(([a, b]) => a + b); console.log(arr); // [ 3, 7 ]解構賦值規則
解構賦值的規則是,只要等號右邊的值不是對象或數組,就先將其轉為對象。由于 undefined 和 null 無法轉為對象,所以對它們進行解構賦值,都會報錯。
let {toString: n} = 123; n === Number.prototype.toString // true let {toString: b} = true; b === Boolean.prototype.toString // true let { prop: u } = undefined; // 報錯 let { prop: n } = null; // 報錯解構賦值的用途
交換變量的值
從對象、數組中取值(提取 JSON 數據),或從函數中返回多個值
函數解構賦值傳參,給定函數參數的默認值
輸入模塊的指定方法
遍歷 Map 結構
const map = new Map(); map.set("first", "hello"); map.set("second", "world"); for (let [key, value] of map) { console.log(key + " is " + value); } // first is hello // second is world字符串擴展(不含編碼) for...of 遍歷字符串
for(let codePoint of "string"){ console.log(codePoint) } // "s" // "t" // "r" // "i" // "n" // "g"includes(),startsWith(),endsWith()
三個方法都接收兩個參數,第一個參數為檢索的值,第二個參數為檢索的起始位置,返回布爾值
let s = "Hello world!"; const [a, b, c] = [ s.startsWith("Hello", 2), s.endsWith("!"), s.includes("o w") ]; console.log(a, b, c); // false true truerepeat()
repeat 方法返回一個新字符串,表示將原字符串重復 n 次。
參數為[-Infinity,-1]或者 Infinity,會報錯;
參數為(-1,1)時,相當于參數為 0;
參數為小數時向下取整;
參數 NaN 等同于 0;
參數是字符串,則會先轉換成數字。
"str".repeat("3") // "strstrstr"padStart(), padEnd()
padStart(),padEnd()有兩個參數,第一個參數為字符串補全生效的最大長度,第二個參數為補全的字符串。
第二個參數默認為空格,省略第二個參數時默認用空格補全。
第一個參數小于字符串原長度時,返回原字符串。
如果用來補全的字符串與原字符串,兩者的長度之和超過了最大長度,則會截去超出位數的補全字符串。
常見用途:補全指定位數,提示字符串格式。
"123456".padStart(10, "0") // "0000123456" "09-12".padStart(10, "YYYY-MM-DD") // "YYYY-09-12"模版字符串(``)
const str = "world"; const template = `Hello ${str}`; console.log(template); // Hello world正則擴展(略) 數值擴展 二進制、八進制表示法
使用二進制表示法,前綴為 0b,使用八進制表示法,前綴為 0o,ES6 不支持使用 00 前綴表示八進制。
進制轉換使用 toString 方法,使用 Number 方法直接轉十進制。
0b1100100 === 100; // true 0o144 === 100; // true (0b1100100).toString(8); // 144 (0b1100100).toString(10); // 100 Number("0b1100100"); // 100Number.isFinite(),Number.isNaN()
Number.isFinite()用來檢查一個數值是否為有限的(finite),即不是 Infinity。參數類型不是數值,Number.isFinite 一律返回 false。
Number.isNaN()用來檢查一個值是否為 NaN。參數類型不是 NaN,Number.isNaN 一律返回 false。
Number.isFinite(15); // true Number.isFinite(-Infinity); // false Number.isNaN(15) // false Number.isNaN(9/0) // trueNumber.parseInt(), Number.parseFloat()
ES6 將全局方法 parseInt()和 parseFloat(),移植到 Number 對象上面,行為完全保持不變。
Number.isInteger()Number.isInteger()用來判斷一個數值是否為整數。
Number.isInteger(25) // true Number.isInteger(25.0) // true Number.isInteger(25.1) // falseES6 新增 Number 常量
Number.EPSILON 極小常量,浮點數誤差小于這個值可以認為不存在誤差;
Number.MAX_SAFE_INTEGER 安全整數的最大范圍;
Number.MIN_SAFE_INTEGER 安全整數的最小范圍;
Number.isSafeInteger() 用來判斷一個整數是否落在安全整數范圍之內。
Number.isSafeInteger(9007199254740993) // false Number.isSafeInteger(990) // true Number.isSafeInteger(9007199254740993 - 990) // trueMath 對象的擴展
Math.trunc() 除去一個數的小數部分,返回整數部分。參數不是數值,內部會先調用 Nunber()專為數值,對于空值和無法截取整數的值,返回 NaN。(Math 對象的擴展的方法對于非數值的處理方法都一樣)
Math.trunc(5.9) // 5 Math.trunc(-4.9) // -4 Math.trunc(null) // 0 Math.trunc("foo"); // NaN
Math.sign() 判斷一個數是正數、負數、還是零。
Math.sign(-5) // -1 負數 Math.sign(5) // +1 正數 Math.sign(0) // +0 零 Math.sign(-0) // -0 零 Math.sign(NaN) // NaN
Math.cbrt() 計算一個數的立方根。
Math.cbrt(2) // 1.2599210498948734 // Math.sqrt(x) 計算平方根 Math.sqrt(2) // 1.4142135623730951 // 冪運算 Math.pow(x,y) Math.pow(2, 3)
Math.hypot() 返回所有參數的平方和的平方根。
Math.hypot(3, 4); // 5 Math.hypot(3, 4, 5); // 7.0710678118654755函數擴展 rest 參數
ES6 引入 rest 參數(形式為...變量名),用于獲取函數的多余參數,rest 參數搭配的變量是一個數組,該變量將多余的參數放入數組中。只能是最后一個參數,函數的 length 屬性,不包括 rest 參數。
function sum1(x, y, ...args) { let sum = 0; for (let arg of args) { sum += arg; } return sum; } console.log(sum1(1, 2, 3, 4)) // 7 function sum2(...args) { return args.reduce((prev, curr) => { return prev + curr }, 0) } console.log(sum2(1, 2, 3)); // 6name 屬性
函數的 name 屬性,返回該函數的函數名。對于匿名函數,ES5 返回"",ES6 返回變量名;
Function 構造函數返回的函數實例,name 屬性的值為 anonymous;bind 返回的函數,name 屬性值會加上 bound 前綴。
function fn() {} fn.name // "fn" function foo() {}; foo.bind({}).name // "bound foo" (function(){}).bind({}).name // "bound "箭頭函數
const fn = v => v; // 等同于 const fn = function (v) { return v; };
注意要點
函數體內的 this 對象,就是定義時所在的對象,而不是使用時所在的對象;
不可以當作構造函數,即不可以使用 new 命令,否則會拋出一個錯誤;
不可以使用 arguments 對象,該對象在函數體內不存在。如果要用,可以用 rest 參數代替;
不可以使用 yield 命令,因此箭頭函數不能用作 Generator 函數。
尾調用優化尾調用指函數的最后一步是調用另一個函數。
function f(x){ "use strict"; return g(x); }
函數調用會在內存形成一個“調用記錄”,又稱“調用幀”(call frame),保存調用位置和內部變量等信息。如果在函數 A 的內部調用函數 B,那么在 A 的調用幀上方,還會形成一個 B 的調用幀。等到 B 運行結束,將結果返回到 A,B 的調用幀才會消失。如果函數 B 內部還調用函數 C,那就還有一個 C 的調用幀,以此類推。所有的調用幀,就形成一個“調用棧”(call stack)。
尾調用由于是函數的最后一步操作,所以不需要保留外層函數的調用幀,因為調用位置、內部變量等信息都不會再用到了,只要直接用內層函數的調用幀,取代外層函數的調用幀就可以了,這樣可以防止內存溢出,達成尾調用優化。
ES6 的尾調用優化只在嚴格模式下開啟,正常模式是無效的。
數組擴展 擴展運算符擴展運算符(spread)是三個點(...)。它好比 rest 參數的逆運算,將一個數組轉為用逗號分隔的參數序列。
const arr = [1, 2, 3]; arr.push(...[4, 5, 6]);
擴展運算符的應用
數組展開
const arr = [1, 2, 3]; ...arr // 1, 2, 3
復制數組
const a1 = [1, 2]; // 寫法一 const a2 = [...a1]; // 寫法二 const [...a2] = a1; // 相當于 const a1 = [1, 2]; const a2 = a1.concat();
合并數組。淺拷貝只是對指針的拷貝,拷貝后兩個指針指向同一個內存空間,深拷貝不但對指針進行拷貝,而且對指針指向的內容進行拷貝,經深拷貝后的指針是指向兩個不同地址的指針。以下的兩種方法屬于淺拷貝,如果修改了原數組的成員,會同步反映到新數組。
const arr1 = ["a", "b"]; const arr2 = ["c"]; const arr3 = ["d", "e"]; // ES5 的合并數組 arr1.concat(arr2, arr3); // [ "a", "b", "c", "d", "e" ] // ES6 的合并數組 [...arr1, ...arr2, ...arr3] // [ "a", "b", "c", "d", "e" ]
解構賦值,字符串轉數組
const list = [1, 2, 3]; [a, ...b] = list; console.log(a) // 1 console.log(b) // [2, 3] [..."hello"] // ["h", "e", "l", "l", "o"]Array.from()
Array.from 方法用于將兩類對象轉為真正的數組:類似數組的對象(array-like object)和可遍歷(iterable)的對象(包括 ES6 新增的數據結構 Set 和 Map)。
常見的類似數組的對象有 DOM 操作返回的 NodeList 集合,以及函數內部的 arguments 對象。
let arrayLike = { "0": "a", "1": "b", "2": "c", length: 3 }; // ES5的寫法 var arr1 = [].slice.call(arrayLike); // ["a", "b", "c"] // ES6的寫法 let arr2 = Array.from(arrayLike); // ["a", "b", "c"] Array.from("hello"); // ["h", "e", "l", "l", "o"] let namesSet = new Set(["a", "b"]); Array.from(namesSet); // ["a", "b"]
Array.from 還可以接受第二個參數,作用類似于數組的 map 方法,用來對每個元素進行處理,將處理后的值放入返回的數組。
let arrayLike = { "0": 1, "1": 2, "2": 3, length: 3 }; Array.from(arrayLike, x => x * x); // [ 1, 4, 9 ]Array.of()
Array.of 方法用于將一組值,轉換為數組。這個方法的主要目的,是彌補數組構造函數 Array()的不足。因為參數個數的不同,會導致 Array()的行為有差異。
Array.of() // [] Array.of(undefined) // [undefined] Array.of(1) // [1] Array.of(1, 2) // [1, 2]copyWithin()
參數:
target(必需):從該位置開始替換數據。如果為負值,表示倒數。
start(可選):從該位置開始讀取數據,默認為 0。如果為負值,表示倒數。
end(可選):到該位置前停止讀取數據,默認等于數組長度。如果為負值,表示倒數。
這三個參數都應該是數值,如果不是,會自動轉為數值。
[1, 2, 3, 4, 5].copyWithin(0, 3)find() 和 findIndex()
數組實例的 find 方法,用于找出第一個符合條件的數組成員,如果沒有符合條件的成員,則返回 undefined。
findIndex 方法返回第一個符合條件的數組成員的位置,如果所有成員都不符合條件,則返回-1。
[1, 4, -5, 10].find(n => n < 0); // -5 [1, 4, -5, 10].findIndex(n => n < 0); // 2
兩個方法都可以接受第二個參數,用來綁定回調函數的 this 對象。
function f(v){ return v > this.age; } let person = {name: "John", age: 20}; [10, 12, 26, 15].find(f, person); // 26
這兩個方法都可以發現 NaN,彌補了數組的 indexOf 方法的不足。
fill() 填充數組fill 方法使用給定值,填充一個數組。fill 方法可以接受第二個和第三個參數,用于指定填充的起始位置和結束位置。如果填充的類型為對象,那么被賦值的是同一個內存地址的對象,而不是深拷貝對象,改變數組中的一項,則所有項都改變。
let arr = Array.of(1, 2, 3).fill({ num: 20 }); console.log(arr); // [ { num: 20 }, { num: 20 }, { num: 20 } ] arr[0].num = 10; console.log(arr); // [ { num: 10 }, { num: 10 }, { num: 10 } ]entries(),keys() 和 values() 遍歷數組
for (let index of ["a", "b"].keys()) { console.log(index); } // 0 // 1 for (let elem of ["a", "b"].values()) { console.log(elem); } // "a" // "b" for (let [index, elem] of ["a", "b"].entries()) { console.log(index, elem); } // 0 "a" // 1 "b"includes()
includes 方法返回一個布爾值,表示某個數組是否包含給定的值,與字符串的 includes 方法類似。該方法的第二個參數表示搜索的起始位置,第二參數是負數,取它的倒數,第二參數大于數組長度,取 0。
[1, 2, 3].includes(3, -1); // trueflat(),flatMap()
flat()默認只會“拉平”一層,如果想要“拉平”多層的嵌套數組,可以將 flat()方法的參數寫成一個整數,表示想要拉平的層數,默認為 1。
flat()的參數為 2,表示要“拉平”兩層的嵌套數組。如果不管有多少層嵌套,都要轉成一維數組,可以用 Infinity 關鍵字作為參數。
[1, [2, [3]]].flat(Infinity); // [1, 2, 3]
flatMap()先遍歷數組,再“拉平”一層,也只能拉平一層。參數魚 map()方法類似。
?
[2, 3, 4].flatMap(x => [x, x * 2]); // [2, 4, 3, 6, 4, 8] // 相當于 [2, 3, 4].map(x => [x, x * 2]).flat(); // [2, 4, 3, 6, 4, 8]對象擴展 屬性簡潔表示法
const a = 1; const b = 2; const c = {a, b}; // 等同于 const c = {a: a, b: b}; const o = { method() { return "Hello!"; } }; // 等同于 const o = { method: function() { return "Hello!"; } }; function f(x, y) { return {x, y}; } // 等同于 function f(x, y) { return {x: x, y: y}; }對象的擴展運算符
對象擴展符類似數組擴展符,主要用于解構賦值。
let { x, y, ...z } = { x: 1, y: 2, a: 3, b: 4 }; x // 1 y // 2 z // { a: 3, b: 4 } let ab = { ...a, ...b }; // 等同于 let ab = Object.assign({}, a, b);Object.is()
Object.is就是部署這個算法的新方法。它用來比較兩個值是否嚴格相等,與嚴格比較運算符(===)的行為基本一致。
Object.is("str", "str"); // true Object.is({}, {}); // false
不同之處只有兩個:一是+0不等于-0,二是NaN等于自身。
+0 === -0 //true NaN === NaN // false Object.is(+0, -0) // false Object.is(NaN, NaN) // trueObject.assign()
Object.assign方法用于對象的合并,將源對象(source)的所有可枚舉屬性,復制到目標對象(target)。
Object.assign方法的第一個參數是目標對象,后面的參數都是源對象。如果目標對象與源對象有同名屬性,或多個源對象有同名屬性,則后面的屬性會覆蓋前面的屬性。
由于undefined和null無法轉成對象,所以如果它們作為首參數,就會報錯。
const target = { a: 1, b: 1 }; const source1 = { b: 2, c: 2 }; const source2 = { c: 3 }; Object.assign(target, source1, source2); target // {a:1, b:2, c:3}
常見用途:
為對象添加屬性和方法
克隆或合并對象
給屬性指定默認值
其他本文參考《ECMAScript 6 入門》,了解更多請點擊跳轉點擊跳轉。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/109152.html
摘要:手把手教你做個人火的時候,隨便一個都能賺的盆滿缽滿,但是,個人沒有服務端,沒有美工,似乎就不能開發了,真的是這樣的嗎秘密花園經典的中文手冊。涵蓋前端知識體系知識結構圖書推薦以及入門視頻教程,全的簡直不要不要的了。 JavaScript 實現點擊按鈕復制指定區域文本 html5 的 webAPI 接口可以很輕松的使用短短的幾行代碼就實現點擊按鈕復制區域文本的功能,不需要依賴 flash。...
摘要:一些知識點有哪些方法方法前端從入門菜鳥到實踐老司機所需要的資料與指南合集前端掘金前端從入門菜鳥到實踐老司機所需要的資料與指南合集歸屬于筆者的前端入門與最佳實踐。 工欲善其事必先利其器-前端實習簡歷篇 - 掘金 有幸認識很多在大廠工作的學長,在春招正式開始前為我提供很多內部推薦的機會,非常感謝他們對我的幫助。現在就要去北京了,對第一份正式的實習工作也充滿期待,也希望把自己遇到的一些問題和...
摘要:平日學習接觸過的網站積累,以每月的形式發布。年以前看這個網址概況在線地址前端開發群月報提交原則技術文章新的為主。 平日學習接觸過的網站積累,以每月的形式發布。2017年以前看這個網址:http://www.kancloud.cn/jsfron... 概況 在線地址:http://www.kancloud.cn/jsfront/month/82796 JS前端開發群月報 提交原則: 技...
摘要:平日學習接觸過的網站積累,以每月的形式發布。年以前看這個網址概況在線地址前端開發群月報提交原則技術文章新的為主。 平日學習接觸過的網站積累,以每月的形式發布。2017年以前看這個網址:http://www.kancloud.cn/jsfron... 概況 在線地址:http://www.kancloud.cn/jsfront/month/82796 JS前端開發群月報 提交原則: 技...
閱讀 2312·2021-11-17 09:33
閱讀 843·2021-10-13 09:40
閱讀 573·2019-08-30 15:54
閱讀 777·2019-08-29 15:38
閱讀 2416·2019-08-28 18:15
閱讀 2475·2019-08-26 13:38
閱讀 1841·2019-08-26 13:36
閱讀 2129·2019-08-26 11:36