国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

ES6學習總結(1)

happyfish / 1723人閱讀

摘要:返回一個對象,遍歷對象自身和繼承的所有可枚舉屬性不含,與相同和在紅寶書中就已經提到過屬性,表示的是引用類型實例的一個內部指針,指向該實例的構造函數的原型對象。

半個月前就決定要將ES6的學習總結一遍,結果拖延癥一犯,半個月就過去了,現在補起來,慚愧慚愧。

阮一峰的《ES6標準入門》這本書有300頁左右,除了幾個新的API和js語法的擴展,真正有價值的內容并不多。所謂“存在即合理”,每部分的內容都對相應的人群有價值,我將結合我在實習中接觸過的ES6的部分和我的個人理解來對這本書的內容做個總結。如有不足或者謬誤指出,還請拍磚。

總結主要從三個方面展開:1. 語法擴展;2. ES6新API; 3. 模塊化方案。

1. 語法擴展 (1)let、const與塊級作用域

let、const聲明的標識符僅在塊級作用域內有效,塊級作用域就是大括號({})包括的區域。const與let的差別在于let聲明的是變量,const聲明的是常量。

let、const不存在變量提升

// let/const不存在變量提升
console.log(foo);   // undefined
var foo = "abc";

console.log(lish);  // 未定義報錯,ReferenceError
let lish = "hello";

let、const暫時性死區:已經聲明了變量,在聲明變量之前,該變量都是不可用的。在局部作用域中,即使已經存在全局的同名變量,還是無法在局部聲明之前訪問該變量,有點繞,直接上代碼。

// 暫時性死區
var num = 1;
const add = () => {
    console.log(num);
    let num;
}
add();      // 報錯,num is not defined

let、const不允許重復聲明,在ES5中,用var聲明的變量我們可以用var重復聲明,就好像重新賦值一樣,但是用let、const重復聲明會報錯。

(2)解構賦值

解構賦值說白了就是“模式匹配”,從等號兩邊對應的位置取出對應的值

數組的解構賦值

let [a, b, c] = [1, 2, 3];
// 從對應位置拿出對應值,相當于我們聲明了三個變量
// let a = 1, b = 2, c = 3;

需要指出一點,只要某種數據具有Iterator接口,就可以采用數組形式的解構賦值(其中就包括字符串),Iterator我們會在總結(2)提到。 舉個例子

// Set是ES6新增的一種數據類型,擁有Iterator接口
let [x, y, z] = new Set([1, 2, 3]); // x = 1, y = 2, z = 3

解構允許指定默認值。默認值有undefined觸發

let [x = 1, y = 2] = [44]; // x = 44, y = 2;
let [x = 1, y = 2] = [44, undefined]; // 與上面等價

對象的解構賦值

只要我們知道這是模式匹配,就比較好理解了,先通過鍵找到對應的值,將值賦給等式左邊相同鍵名對應的變量,{foo}就是{foo: foo}的簡寫形式,這屬于對象的擴展,接下來會提到。

let { foo, bar } = { foo: "hello", bar: "world" };  // foo = "hello", bar = "world"
let {foo: val, bar} =  { foo: "hello", bar: "world" };  // val = "hello", bar = "world";

和數組解構類似,也可以為對象解構賦默認值let {x = 3} = {};,默認值由undefined觸發。
需要注意的一點是,大括號不能出現在行首,會被解析為代碼塊,比如{x} = {x: 1};

函數參數的解構賦值

參數可以為數組或對象
比如:我們為函數直接傳一個數組,在函數內部我們直接可以使用解構后的值

const add = ([x, y]) => {
    return x + y;
}
console.log(add([1, 2]);    // 3
console.log(add.length);    // 1

上面代碼中,比較好理解的是add.length,代表函數參數的個數,但是我們為參數指定默認值時, length為0,原因就是函數的length屬性為沒有指定默認值的參數的個數,而且不包括rest參數

const add = ([x, y] = [0, 0]) => {
    return x + y;
}
console.log(add());    // 0
console.log(add.length);    // 0
(3)模板字符串

字符串擴展中,最有用的就是模板字符串,用反引號(`)標識,模板字符串中可以使用變量,省去了用連接符來拼接字符串的麻煩。

let foo = "hello";
console.log(`${foo} world!`);   // hello world

看了上面,相信大家都會在模板字符串中使用變量了,就是講變量寫在${}中就行了。
另外,模板字符串中還可以使用表達式(包括函數調用,運算等),同樣,將表達式寫在${}中就行了。

(4)擴展運算符(...)與 rest參數

擴展運算符
作用:將一個數組(姑且先說是數組)轉換為用逗號分隔的參數序列。

console.log([1, 2, ...[2, 3, 4]]); // [1, 2, 2, 3, 4]
console.log(..."hello"); // h e l l o

// generator函數
let go = function* () {
    yield 1;
    yield 2;
    yield 3;
};
console.log(...go());   // 1 2 3

問題來了:擴展運算符可以作用于哪些數據類型呢?

回答這個問題很關鍵,直接說答案吧:擁有Iterator接口的數據類型

rest參數

阮大神的書上原話:rest參數(...變量名),用于獲取函數多余的參數,放進一個數組中。

const add = function (arg1, ...values) {
    return values;
};
console.log(add(1, 3, 5, 7));   // [3, 5, 7]

個人之見,這句話有點問題,rest參數好比是擴展運算符的逆運算,怎么能只用于獲取函數多余的參數呢,事實證明,rest不僅僅用于獲取函數參數。
我們看上的函數定義部分的參數和函數調用部分的參數,這不就是一個模式匹配嗎?arg1對應第一個參數,...values對應剩余的參數。說道模式匹配,不得不說解構賦值,那么我們在解構賦值中應用rest參數呢,下面我們試試看

let values, num;
[num, ...values] = [1, 3, 5, 7];
console.log(values);    // [3, 5, 7]

實驗證明rest參數也可以用于解構賦值中,要注意的是rest參數只能放在其他參數的后面,否則rest參數無法判斷里面參數的個數

(5)數組的擴展

Array.from()
作用: 將類似數組的對象和可遍歷的對象(擁有Iterator接口)轉為真正的數組

所謂類似數組的對象,關鍵在于有沒有一個length屬性表示對象中屬性的個數

var obj = {0: "hello", "sayName": "hi", 1: "world", length: 2};
console.log(Array.from(obj));   //["hello", "world"];

上面轉換的只是鍵名為數字的屬性

Array.of()
作用:將一組數值轉換為數組,主要目的為了彌補Array構造函數不能識別長度還是值。

實例方法find()和findIndex()
find()找到第一個符合條件的數組成員,參數為函數,返回true表示找到

findIndex(),與find()類似,返回的是數組的索引。

遍歷方法entries()、keys()、values()
都返回遍歷器對象,便利器對象可用for...of進行遍歷

for(let index of ["a", "b"].keys()) {
    console.log(index);
}
// 0
// 1

for(let value of ["a", "b"].values()) {
    console.log(value);
}
// a
// b

for(let [index, value] of ["a", "b"].entries()){
    console.log(index, value);
}
// 0 a
// 1 b

includes()
作用:判斷數組是否包含某個值,屬于ES7,客戶端使用要使用Babel進行轉碼,為了彌補indexOf()的不足,indexOf()內部使用“===”進行判斷,對于NaN的判斷會出錯,而includes()解決了這個問題

console.log([NaN, NaN].indexOf(NaN));   // -1
console.log([NaN, NaN].includes(NaN));  // true
(6)函數的擴展

函數參數的解構賦值,默認值在第一部分已經提到,這里就不再總結,在函數擴展這一部分,我主要總結箭頭函數的使用
ES6中可以使用箭頭函數定義函數,方式如下:

const f = (arg1) => {
    return arg1 * 2;
}
const f = arg1 => arg1*2;     // 等同于上面的定義

當參數只有一個時,可以省略括號,當函數體只有return語句一條語句時,可以省略大括號和return關鍵字

使用箭頭函數需要注意的幾點

箭頭函數不可以當做構造函數

不可以使用arguments對象

不可以使用yield命令,不能用作generator函數

箭頭函數沒有自己的this,導致內部的this就是外層代碼的this,所以不能用作構造函數,也不能使用call()、apply()、bind()改變this的指向

(7)對象的擴展

屬性的簡潔表示法

變量名轉屬性名

let foo = "hello";
let obj = {foo: foo};

// 簡寫形式
let foo = "hello";
let obj = {foo};    // 變量名直接轉為屬性名

方法的簡寫

let obj = {
    sayName: function() {
        return "hello";
    }
}

// 簡寫形式
let obj = {
    sayName() {
        return "hello";
    }
};

ES6允許字面量定義對象時使用表達式作為對象的屬性名
將表達式放在中括號中,但是屬性名表達式與簡潔表示法不能同時使用

let obj = {
    ["a" + "bc"]: 123
}

Object.is()
用來比較兩個值是否嚴格相等,與“===”行為基本一致,不同之處在于: +0不等于-0,NaN等于自身

Object.assign()
將源對象的所有可枚舉的自有屬性復制(淺復制)到目標對象Object.assign(target, source1, source2 ...),返回target,可以處理數組,將其視為對象

let target = {a: 1};
let source1 = {b: 2};
let source2 = {c: 3};
Object.assign(target, source1, source2);
// target => {a: 1, b: 2, c: 3};

一般情況下,我們不希望改變對象,只希望合并對象的屬性,那么可以將target設為空對象{}, Object.assign({}, source1, source2);

需要注意的是Object.assign()執行的是淺復制, 如果源對象的屬性為引用類型,那么target中對應的屬性和源對象中的屬性引用同一個值

let source1 = {b: {test: "hello world"}};
let target = Object.assign({}, source1);

console.log(target.b);  // { test: "hello world" }

source1.b.test = 111111;
console.log(target.b);  // {test: 111111}

對象的屬性的遍歷

for...in 循環遍歷對象自身和繼承的可枚舉屬性(不含Symbol屬性),Symbol是ES6中的一種新的數據類型,表示一個獨一無二的值,在第二大部分,我將會講到這個類型。
Object.keys(obj) 返回數組,包括對象自身的所有可枚舉屬性(不含Symbol屬性)
Object.getOwnPropertyNames(obj) 返回數組,包含對象自身的所有屬性(包括不可枚舉屬性,不包含Symbol屬性)

說白了,就是ES5中遍歷方法都無法獲取到Symbol屬性

Object.getOwnPropertySymbols(obj)返回數組,包含自身的所有Symbol屬性
Reflect.ownKeys(obj)返回一個數組,包含對象自身的所有屬性(包括不可枚舉和Symbol), Reflect是ES6中的新API,其目的之一就是將Object對象上一些屬于語言層面的方法放到該對象身上,并修改某些方法,讓其變得更合理。
Reflect.enumerate(obj)返回一個Iterator對象,遍歷對象自身和繼承的所有可枚舉屬性(不含Symbol),與for...in相同

__proto__和Object.setPrototype()

在紅寶書中就已經提到過__proto__屬性,表示的是引用類型實例的一個內部指針,指向該實例的構造函數的原型對象。一般不建議我們直接使用,因為這是一個非標準屬性,但是所有瀏覽器都部署了這個屬性,node中也可以使用

// 利用__proto__實現繼承
function Animal(name) {
    this.name = name;
}
Animal.prototype.sayName = function() {
    console.log(this.name);
};

function Dog(name, leg) {
    Animal.call(this, name);
    this.leg = leg;
}
Dog.prototype.__proto__ = Animal.prototype;
Dog.prototype.constructor = Dog;

var dog = new Dog("Genkle", 4);
dog.sayName();  // Genkle

Object.setPrototype(object, prototype)用于設置一個對象的prototype對象,相當于object.__proto__ = prototype,是ES6中設置原型對象的方法。

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/82388.html

相關文章

  • ES6學習總結(二)

    摘要:關于的學習總結昨天寫了第一篇,主要是關于變量聲明關鍵字和,新增類型以及模板字符串,今天準備寫第二篇,里面的函數部分,新增了箭頭函數,參數以及參數默認值。,這次我們在調用函數大的時候,兩個參數全部傳遞了值,因此返回。 關于ES6的學習總結,昨天寫了第一篇,主要是關于變量聲明關鍵字let和const,新增類型Symbol以及模板字符串,今天準備寫第二篇,ES6里面的函數部分,ES6新增了箭...

    microelec 評論0 收藏0
  • ES6解構賦值學習總結

    摘要:提供了解構賦值的方式,這樣子在賦值多個變量或者進行注釋時可以方便很多,不同場景下也有很多新的應用,個人常使用的有數組的解構賦值,對象的解構賦值和函數參數的解構賦值,函數參數的解構賦值之前總結過,這里寫下數組的和對象的簡單總結吧函數參數的解構 ES6提供了解構賦值的方式,這樣子在賦值多個變量或者進行注釋時可以方便很多,不同場景下也有很多新的應用,個人常使用的有數組的解構賦值,對象的解構賦...

    levinit 評論0 收藏0
  • ES6學習總結(三)

    摘要:不同于其他面向對象語言,以前的中中沒有類的概念,主要是通過原型的方式來實現繼承,中引入了原型鏈,并且將原型鏈用來實現繼承,其核心是利用原型使得一個對象繼承另一個對象的方法和屬性,中原型繼承的關鍵是將一個實例的原型對象指向另一個實例,因此前一 不同于其他面向對象語言,ES6以前的JavaScript中中沒有class類的概念,主要是通過原型的方式來實現繼承,JavaScript中引入了原...

    baoxl 評論0 收藏0
  • ES6學習總結(一)

    摘要:可以通過調用方法將創建一個新的類型的值,這個值獨一無二,不與任何值相等。還可以使可擴展,在中,表達式被標準化為構造函數的一個方法,這意味著它是可擴展的。 前端發展的太快了,快到ES6,ES7出來之后,今年已經是ES8了,但是縱然前端發展很快,我們除了馬不停蹄的學習新的技術之外,也要沉下心來,好好的潛心磨礪自己,本文是整理了自己學習ES6之后相關的知識要點,寄希望于書之于筆,一來自己可以...

    _ipo 評論0 收藏0
  • ES6-7

    摘要:的翻譯文檔由的維護很多人說,阮老師已經有一本關于的書了入門,覺得看看這本書就足夠了。前端的異步解決方案之和異步編程模式在前端開發過程中,顯得越來越重要。為了讓編程更美好,我們就需要引入來降低異步編程的復雜性。 JavaScript Promise 迷你書(中文版) 超詳細介紹promise的gitbook,看完再不會promise...... 本書的目的是以目前還在制定中的ECMASc...

    mudiyouyou 評論0 收藏0

發表評論

0條評論

最新活動
閱讀需要支付1元查看
<