ES6面試題大全

以下題目是根據(jù)網(wǎng)上多份面經(jīng)收集而來(lái)的鸠姨,題目相同意味著被問(wèn)的頻率比較高叙甸,有問(wèn)題歡迎留言討論钉迷,喜歡可以點(diǎn)贊關(guān)注出皇。

image.png
1.let const var比較區(qū)別,ES6中l(wèi)et塊作用域是怎么實(shí)現(xiàn)的

https://github.com/Advanced-Frontend/Daily-Interview-Question/issues/133

先說(shuō)說(shuō)這三者的區(qū)別吧:

可以結(jié)合http://www.reibang.com/p/47b49d7bdfc2中的第一節(jié)來(lái)看堂竟。

(一)var

  • var 命令會(huì)發(fā)生“變量提升”現(xiàn)象魂毁,即變量可以在聲明之前使用,值為 undefined
  • 內(nèi)層變量可能覆蓋外層變量
  • 用來(lái)計(jì)數(shù)的循環(huán)變量泄露為全局變量

(二)let

  • 聲明的全局變量不會(huì)掛在頂層對(duì)象下面
  • 所聲明的變量一定要在聲明后使用出嘹,否則報(bào)錯(cuò)席楚,報(bào)錯(cuò) ReferenceError
  • 暫時(shí)性死區(qū),只要塊級(jí)作用域內(nèi)存在 let 命令税稼,它所聲明的變量就“綁定”( binding )這個(gè)區(qū)域烦秩,不再受外部的影響,在代碼塊內(nèi)娶聘,使用 let 命令聲明變量之前闻镶,該變量都是不可用的甚脉。
  • 不允許重復(fù)聲明

(三)const

  • 聲明的全局變量不會(huì)掛在頂層對(duì)象下面
  • const 聲明之后必須馬上賦值丸升,否則會(huì)報(bào)錯(cuò)
  • const 簡(jiǎn)單類型一旦聲明就不能再更改,復(fù)雜類型(數(shù)組牺氨、對(duì)象等)指針指向的地址不能更改狡耻,內(nèi)部數(shù)據(jù)可以更改。
  • const 一旦聲明變量猴凹,就必須立即初始化夷狰,不能留到以后賦值。
  • const 命令聲明的常量也是不提升郊霎,同樣存在暫時(shí)性死區(qū)沼头,只能在聲明的位置后面使用

如 const 聲明了一個(gè)復(fù)合類型的常量,其存儲(chǔ)的是一個(gè)引用地址书劝,不允許改變的是這個(gè)地址进倍,而對(duì)象本身是可變的。

//      const arr 數(shù)組可以賦值
        const arr = ['apple', 'banana']
        arr.push('orange')
        console.log(arr)//["apple", "banana", "orange"]
然后是原理购对,原理確實(shí)沒(méi)認(rèn)真研究過(guò)猾昆,在網(wǎng)上翻了一番資料,結(jié)合自己的理解簡(jiǎn)單說(shuō)下(純屬個(gè)人愚見(jiàn)骡苞,高手輕噴)

變量與內(nèi)存之間的關(guān)系垂蜗,主要由三個(gè)部分組成:

  1. 變量名
  2. 內(nèi)存地址
  3. 內(nèi)存空間

JS 引擎在讀取變量時(shí)楷扬,先找到變量綁定的內(nèi)存地址,然后找到地址所指向的內(nèi)存空間贴见,最后讀取其中的內(nèi)容烘苹。當(dāng)變量改變時(shí),JS 引擎不會(huì)用新值覆蓋之前舊值的內(nèi)存空間(雖然從寫代碼的角度來(lái)看片部,確實(shí)像是被覆蓋掉了)螟加,而是重新分配一個(gè)新的內(nèi)存空間來(lái)存儲(chǔ)新值,并將新的內(nèi)存地址與變量進(jìn)行綁定吞琐,JS 引擎會(huì)在合適的時(shí)機(jī)進(jìn)行 GC捆探,回收舊的內(nèi)存空間。

const 定義變量(常量)后站粟,變量名與內(nèi)存地址之間建立了一種不可變的綁定關(guān)系黍图,阻隔變量地址被改變,當(dāng) const 定義的變量進(jìn)行重新賦值時(shí)奴烙,根據(jù)前面的論述助被,JS 引擎會(huì)嘗試重新分配新的內(nèi)存空間,所以會(huì)被拒絕切诀,便會(huì)拋出異常揩环。

var的話會(huì)直接在棧內(nèi)存里預(yù)分配內(nèi)存空間,然后等到實(shí)際語(yǔ)句執(zhí)行的時(shí)候幅虑,再存儲(chǔ)對(duì)應(yīng)的變量丰滑,如果傳的是引用類型,那么會(huì)在堆內(nèi)存里開(kāi)辟一個(gè)內(nèi)存空間存儲(chǔ)實(shí)際內(nèi)容倒庵,棧內(nèi)存會(huì)存儲(chǔ)一個(gè)指向堆內(nèi)存的指針

ES6中l(wèi)et塊作用域是怎么實(shí)現(xiàn)的

let的話褒墨,是不會(huì)在棧內(nèi)存里預(yù)分配內(nèi)存空間,而且在棧內(nèi)存分配變量時(shí)擎宝,做一個(gè)檢查郁妈,如果已經(jīng)有相同變量名存在就會(huì)報(bào)錯(cuò)。也就是暫時(shí)性死區(qū)绍申,只要塊級(jí)作用域內(nèi)存在 let 命令噩咪,它所聲明的變量就“綁定”( binding )這個(gè)區(qū)域,不再受外部的影響极阅,在代碼塊內(nèi)胃碾,使用 let 命令聲明變量之前,該變量都是不可用的涂屁。

const的話书在,也不會(huì)預(yù)分配內(nèi)存空間,在棧內(nèi)存分配變量時(shí)也會(huì)做同樣的檢查拆又。不過(guò)const存儲(chǔ)的變量是不可修改的儒旬,對(duì)于基本類型來(lái)說(shuō)你無(wú)法修改定義的值栏账,對(duì)于引用類型來(lái)說(shuō)你無(wú)法修改棧內(nèi)存里分配的指針,但是你可以修改指針指向的對(duì)象里面的屬性

2.反引號(hào)(`)標(biāo)識(shí)(模板字符串)

https://blog.csdn.net/zwt_guiji/article/details/81979299

模板字符串是在ES6中興起

用法

// 普通字符串
`In JavaScript '\n' is a line-feed.` 
// 多行字符串
`In JavaScript this 
isnot legal.`
// 字符串中嵌入變量
var name = "Bob", time = "today";
`Hello ${name}, how are you ${time}?` // Hello Bob, how are you today?

模板字符串都是用反引號(hào)表示栈源,如果在模板字符串中需要使用反引號(hào)挡爵,則前面需要用反斜杠轉(zhuǎn)義。

如果使用模板字符串表示多行字符串甚垦,則所有的空格茶鹃、縮進(jìn)和換行都會(huì)被保留在輸出中。比如<ul>標(biāo)簽前面會(huì)有一個(gè)換行艰亮。如果想把行首和行尾的換行闭翩、空格等去掉,則使用trim方法即可迄埃。

模板字符串中嵌入變量疗韵,要將變量名寫在${}之中。大括號(hào)內(nèi)可以放入任意的JavaScript表達(dá)式侄非,可以進(jìn)行運(yùn)算蕉汪,以及引入對(duì)象屬性。

模板字符串之中還可以調(diào)用函數(shù)逞怨。

如果大括號(hào)中的值不是字符串者疤,則將按照一般的規(guī)則轉(zhuǎn)換為字符串。如叠赦,若大括號(hào)中是一個(gè)對(duì)象驹马,則將默認(rèn)調(diào)用對(duì)象的toString方法,把對(duì)象轉(zhuǎn)換為字符串眯搭。

如果模板字符串中的變量沒(méi)有聲明窥翩,則會(huì)報(bào)錯(cuò)。

// 變量place沒(méi)有聲明
var msg = `Hello, ${place}`;
// ReferenceError: place is not defined

模板字符串之間還可以進(jìn)行嵌套鳞仙。

標(biāo)簽?zāi)0?/h3>

模板字符串的功能,不僅是上面那些笔时,它還可以緊跟在一個(gè)函數(shù)后面棍好,該函數(shù)將被調(diào)用來(lái)處理這個(gè)模板字符串,這種稱為“標(biāo)簽?zāi)0濉惫δ?Tagged template)允耿。

alert`123`// 等同于alert(123)

標(biāo)簽?zāi)0迤渌且环N特殊的函數(shù)調(diào)用形式借笙,“標(biāo)簽”指的就是函數(shù),緊跟在后面的模板字符串就是它的參數(shù)较锡。

var a = 1,    b = 2;
 tag`Helo ${a + b} world ${a * b}`;

上面代碼中业稼,模板字符串前面有一個(gè)標(biāo)識(shí)名tag,它是一個(gè)函數(shù)蚂蕴。整個(gè)表達(dá)式的返回值就是tag函數(shù)處理模板字符串后的返回值低散。

函數(shù)tag依次會(huì)接收到多個(gè)參數(shù)俯邓。

tag函數(shù)的第一個(gè)參數(shù)是一個(gè)數(shù)組,該數(shù)組的成員是模板字符串中那些沒(méi)有變量替換的部分熔号,也就是說(shuō)稽鞭,變量替換只發(fā)生在數(shù)組的第一個(gè)成員與第二個(gè)成員之間、第二個(gè)成員與第三個(gè)成員之間引镊,以此類推朦蕴。tag函數(shù)的其他參數(shù),都是模板字符串各個(gè)變量被替換的值弟头。本例中吩抓,模板字符串含有兩個(gè)變量,因此tag會(huì)接收到value1和value2兩個(gè)參數(shù)赴恨。

tag函數(shù)所有參數(shù)的實(shí)際值如下:

  • 第一個(gè)參數(shù): [‘Hello ‘, ’ world’, ”]
  • 第二個(gè)參數(shù): 3
  • 第三個(gè)參數(shù): 2

也就是說(shuō)琴拧,tag函數(shù)實(shí)際上是用下面的形式調(diào)用:

tag(['Hello ',' world', ''], 3, 2);

String對(duì)象的raw方法

String.raw方法用來(lái)充當(dāng)模板字符串的處理函數(shù),返回一個(gè)除表達(dá)式和變量會(huì)被替換嘱支,其它都保持原樣的字符串蚓胸。

String.raw方法可以作為處理模板字符串的基本方法,它會(huì)將所有變量替換除师,而且對(duì)斜杠進(jìn)行轉(zhuǎn)義沛膳,方便下一步作為字符串來(lái)使用。

3.函數(shù)默認(rèn)參數(shù)和剩余(rest)參數(shù)

詳細(xì)解析點(diǎn)擊鏈接

    1. 函數(shù)默認(rèn)參數(shù)
        function show({x=0,y=0}={}){
            console.log(x,y);
        }
        show()
    2. 函數(shù)參數(shù)默認(rèn)已經(jīng)定義了汛聚,不能再使用let锹安,const聲明
        function show(a=18){
            let a = 101;  //錯(cuò)誤
            console.log(a);
        }
        show()

擴(kuò)展運(yùn)算符、Reset運(yùn)算符:
    ...

    展開(kāi)數(shù)組

    ... :
        [1,2,3,4]  -> ... [1,2,3,4]  ->  1,2,3,4,5
    ...:
        1,2,3,4,5  -> ...1,2,3,4,5  ->  [1,2,3,4,5]

    剩余參數(shù): 必須放到最后

rest參數(shù)和 arguments對(duì)象的區(qū)別

image.png

4.箭頭函數(shù)this指向問(wèn)題倚舀,箭頭函數(shù)與普通函數(shù)的區(qū)別叹哭,你說(shuō)箭頭函數(shù)沒(méi)有自己的this,那(()=>{}).bind(this)可以么?

https://juejin.im/post/5b14d0b4f265da6e60393680

image.png

六沒(méi)
1痕貌、沒(méi)有this
箭頭函數(shù)沒(méi)有 this风罩,所以需要通過(guò)查找作用域鏈來(lái)確定 this 的值。這就意味著如果箭頭函數(shù)被非箭頭函數(shù)包含舵稠,this 綁定的就是最近一層非箭頭函數(shù)的 this超升。,因?yàn)榧^函數(shù)沒(méi)有 this哺徊,所以也不能用 call()室琢、apply()、bind() 這些方法改變 this 的指向落追,可以看一個(gè)例子:

var value = 1;
var result = (() => this.value).bind({value: 2})();
console.log(result); // 1

2盈滴、沒(méi)有arguments
箭頭函數(shù)沒(méi)有自己的 arguments 對(duì)象,這不一定是件壞事轿钠,因?yàn)榧^函數(shù)可以訪問(wèn)外圍函數(shù)的巢钓。通過(guò)命名參數(shù)或者 rest 參數(shù)的形式訪問(wèn)參數(shù)

3病苗、沒(méi)有new關(guān)鍵字調(diào)用
箭頭不能被用作構(gòu)造函數(shù),如果通過(guò) new 的方式調(diào)用竿报,會(huì)報(bào)錯(cuò)

var Foo = () => {};
var foo = new Foo(); // TypeError: Foo is not a constructor

4铅乡、沒(méi)有new.target
因?yàn)椴荒苁褂?new 調(diào)用,所以也沒(méi)有 new.target 值烈菌。關(guān)于 new.target阵幸,可以參考 es6.ruanyifeng.com/#docs/class…

5、沒(méi)有原型
由于不能使用 new 調(diào)用箭頭函數(shù)芽世,所以也沒(méi)有構(gòu)建原型的需求挚赊,于是箭頭函數(shù)也不存在 prototype 這個(gè)屬性。

var Foo = () => {};
console.log(Foo.prototype); // undefined

6济瓢、沒(méi)有super
連原型都沒(méi)有荠割,自然也不能通過(guò) super 來(lái)訪問(wèn)原型的屬性,所以箭頭函數(shù)也是沒(méi)有 super 的旺矾,不過(guò)跟 this蔑鹦、arguments、new.target 一樣箕宙,這些值由外圍最近一層非箭頭函數(shù)決定嚎朽。

5.屬性簡(jiǎn)寫

1.對(duì)象的方法簡(jiǎn)寫

const o = {
  method() {
    return "Hello!";
  }
};

// 等同于

const o = {
  method: function() {
    return "Hello!";
  }
};

let birth = '2000/01/01';
const Person = {
  name: '張三',
  //等同于birth: birth
  birth,
  // 等同于hello: function ()...
  hello() { console.log('我的名字是', this.name); }
};
2.對(duì)象的屬性簡(jiǎn)寫

const a= 'a';
const b= {a};                    
b// {a: "a"}
// 等同于
const b= {a: a};             //前面的a是對(duì)象屬性的名字,后面的a代表變量a

實(shí)際應(yīng)用:
function f(x, y) {
  return {x, y};
}

// 等同于

function f(x, y) {
  return {x: x, y: y};
}

f(1, 2) // {x: 1, y: 2}
3.擴(kuò)展


import App from './App.vue'
new Vue({
   router,
   store,
   render: h => h(App)
 })

等同于

new Vue({
  router:router,
  store:store,
  render:function(h){
      return  h(App);
  }
})
6.方法簡(jiǎn)寫

同上

7.Object.keys()方法柬帕,獲取對(duì)象的所有屬性名或方法名

一哟忍、語(yǔ)法

Object.keys(obj)
參數(shù):要返回其枚舉自身屬性的對(duì)象
返回值:一個(gè)表示給定對(duì)象的所有可枚舉屬性的字符串?dāng)?shù)組

二、處理對(duì)象陷寝,返回可枚舉的屬性數(shù)組

let person = {name:"張三",age:25,address:"深圳",getName:function(){}}
Object.keys(person) // ["name", "age", "address","getName"]
image

三锅很、處理數(shù)組,返回索引值數(shù)組

let arr = [1,2,3,4,5,6]
Object.keys(arr) // ["0", "1", "2", "3", "4", "5"]
image

四凤跑、處理字符串爆安,返回索引值數(shù)組

let str = "saasd字符串"
Object.keys(str) // ["0", "1", "2", "3", "4", "5", "6", "7"]
image

五、常用技巧

let person = {name:"張三",age:25,address:"深圳",getName:function(){}}
Object.keys(person).map((key)=>{
person[key] // 獲取到屬性對(duì)應(yīng)的值饶火,做一些處理
}) 

六鹏控、Object.values()和Object.keys()是相反的操作,把一個(gè)對(duì)象的值轉(zhuǎn)換為數(shù)組

8.Object.assign ()原對(duì)象的屬性和方法都合并到了目標(biāo)對(duì)象

http://www.reibang.com/p/f9ec860ecd81

    Object.assign():   用來(lái)合并對(duì)象
    let 新的對(duì)象 = Object.assign(目標(biāo)對(duì)象, source1, srouce2....)

    function ajax(options){  //用戶傳
        let defaults={
            type:'get',
            header:
            data:{}
            ....
        };

        let json = Object.assign({}, defaults, options);
        .....
    }
    
    用途:
        1. 復(fù)制一個(gè)對(duì)象
        2. 合并參數(shù)

    let json = { a: 3, b: 4 };
    let json2 = { ...json };
    console.log(json2 === json)//false
    console.log(Object.assign({}, json) === json)//false
    console.log(Object.assign(json) === json)//true

注意:
1.如果目標(biāo)對(duì)象中的屬性具有相同的鍵肤寝,則屬性將被源對(duì)象中的屬性覆蓋。后面的源對(duì)象的屬性將類似地覆蓋前面的源對(duì)象的屬性
2.Object.assign 方法只會(huì)拷貝源對(duì)象自身的并且可枚舉的屬性到目標(biāo)對(duì)象抖僵。該方法使用源對(duì)象的[[Get]]和目標(biāo)
對(duì)象的[[Set]]鲤看,所以它會(huì)調(diào)用相關(guān) getter 和 setter。因此耍群,它分配屬性义桂,而不僅僅是復(fù)制或定義新的屬性找筝。如
果合并源包含getter,這可能使其不適合將新屬性合并到原型中慷吊。為了將屬性定義(包括其可枚舉性)復(fù)制到
原型袖裕,應(yīng)使用Object.getOwnPropertyDescriptor()和Object.defineProperty() 。

9.for...of 循環(huán)

http://www.reibang.com/p/2e6dd8906e97

一個(gè)數(shù)據(jù)結(jié)構(gòu)只要部署了Symbol.iterator屬性溉瓶,就被視為具有 iterator 接口急鳄,就可以用for...of循環(huán)遍歷它的成員。也就是說(shuō)堰酿,for...of循環(huán)內(nèi)部調(diào)用的是數(shù)據(jù)結(jié)構(gòu)的Symbol.iterator方法疾宏。for...of循環(huán)可以使用的范圍包括數(shù)組、Set 和 Map 結(jié)構(gòu)触创、某些類似數(shù)組的對(duì)象(比如arguments對(duì)象坎藐、DOM NodeList 對(duì)象)、Generator 對(duì)象哼绑,以及字符串岩馍。

for...of 遍歷 非 Iterator 的類數(shù)組對(duì)象

并不是所有類似數(shù)組的對(duì)象都具有 Iterator 接口,一個(gè)簡(jiǎn)便的解決方法抖韩,就是使用Array.from方法將其轉(zhuǎn)為數(shù)組蛀恩。

let arrayLike = { length: 2, 0: 'a', 1: 'b' };

// 報(bào)錯(cuò)
for (let x of arrayLike) {
  console.log(x);
}

// 正確
for (let x of Array.from(arrayLike)) {
  console.log(x);
}

for...of 遍歷 對(duì)象
對(duì)于普通的對(duì)象,for...of結(jié)構(gòu)不能直接使用帽蝶,會(huì)報(bào)錯(cuò)赦肋。使用 for...in 可以遍歷對(duì)象的鍵名。

let obj = {
    a: 1,
    b: 2,
    c: 3
}

for (let e in obj) {
    console.log(e);  // 'a'  'b'  'c'
}

總之励稳,for...in循環(huán)主要是為遍歷對(duì)象而設(shè)計(jì)的佃乘,不適用于遍歷數(shù)組。

一種解決方法是驹尼,使用Object.keys方法將對(duì)象的鍵名生成一個(gè)數(shù)組趣避,然后再用 for...of 遍歷這個(gè)數(shù)組。

for(let key of Object.keys(obj)) {
    console.log(key + ': ' + obj[key]);
}

另一個(gè)方法是使用 Generator 函數(shù)將對(duì)象重新包裝一下新翎。

function* entries(obj) {
    for(let key of Object.keys(obj)) {
        yield [key, obj[key]];
    }
}
for(let [key, value] of entries(obj)) {
    console.log(key, '->', value);
}

9程帕、for...of 可以與 break / continue / return 配合使用

for (var n of arr) {
    if (n > 10) {
        break;
    }
    console.log(n);
}
10.import和export,CommonJS 中的 require/exports 和 ES6 中的 import/export 區(qū)別地啰?

1愁拭、CommonJS模塊輸出的是一個(gè)值的拷貝,一旦輸出一個(gè)值亏吝,模塊內(nèi)部的變化就影響不到這個(gè)值岭埠。

  ES6模塊輸出的是值的引用,JS引擎對(duì)腳本靜態(tài)分析的時(shí)候,遇到模塊加載命令import惜论,就會(huì)生成一個(gè)只讀引用许赃。等到腳本真正執(zhí)行時(shí),在根據(jù)引用到被加載的那個(gè)模塊里面去取值馆类。ES6模塊是動(dòng)態(tài)引用混聊,并且不會(huì)緩存運(yùn)行結(jié)果,而是動(dòng)態(tài)的去被加載的模塊取值乾巧,模塊里面的變量綁定其所在的模塊句喜。

2、CommonJS模塊是運(yùn)行時(shí)加載卧抗,ES6模塊是編譯時(shí)輸出接口(ES6可以在編譯時(shí)就完成模塊加載藤滥,效率要比CommonJS模塊的加載方式高)。

  1. ES6模塊是通用的社裆,同一個(gè)模塊不用修改拙绊,就可以用在瀏覽器

4、require/exports是CommonJS在Node中實(shí)現(xiàn)的泳秀。

  import/export是ES6的模塊标沪,對(duì)ES6只要使用babel就可以了

5、ES6模塊的設(shè)計(jì)思想嗜傅,是盡量靜態(tài)化金句,使得編譯時(shí)就能確定模塊的依賴關(guān)系以及輸入和輸出的變量。export命令用于規(guī)定模塊的對(duì)外接口吕嘀,import命令用于輸入其他模塊提供的功能违寞。

12.解構(gòu)賦值

非常有用,特別在做數(shù)據(jù)交互 ajax

let [a,b,c] =[12,5, 6];

注意: 左右兩邊偶房,結(jié)構(gòu)格式要保持一致

        // let [a, b, c] = [12, 3, 'k']
        // console.log(a, b, c)//12 3 "k"

        // 屬性名稱要一一對(duì)應(yīng)
        // let { name, age, job, f, arr } = {
        //     name: 'Strive',
        //     age: 18,
        //     job: '碼畜',
        //     arr: [
        //         { name: 'liu' },
        //         { name: 'zhao' }
        //     ]
        // };
        // console.log(name, age, job, f)//Strive 18 碼畜 undefined
        // console.log(name, age, job, arr)//Strive 18 碼畜 (2) [{…}, {…}]

        // let json = {
        //     name: 'Strive',
        //     age: 18,
        //     job: '碼畜',
        //     arr: [
        //         { name: 'liu' },
        //         { name: 'zhao' }
        //     ]
        // };
        // let { name: n, age: g, job: f, arr } = json;
        // console.log(n, g, f, arr)//Strive 18 碼畜 (2) [{…}, {…}]

        // let [a, b, c] = ['a', 'b']
        // console.log(a, b, c)//a b undefined

        // 傳undefined和上面不傳參數(shù)是一樣的 傳null和‘’都是有值
        // let [a, b, c] = ['a', 'b', undefined]
        // console.log(a, b, c)//a b undefined

        // let [a, b, c = 'no-data'] = ['a', 'b']
        // console.log(a, b, c)//a b no-data

        // let a;
        // //先用let定義沒(méi)有賦值  要用小括號(hào)括起來(lái)  不然大括號(hào)直接暴露在外面  會(huì)起到塊級(jí)作用域的
        // ({ a } = { a: 'apple', b: 'banana' });
        // console.log(a)

        // a,b相互賦值 不用找中間值
        // let a = 12;
        // let b = 10;
        // [a, b] = [b, a]
        // console.log(a)//10

        // function fn() {
        //     return {
        //         leftVal: 10,
        //         topVal: 20
        //     }
        // }

        // let { leftVal, topVal: t } = fn();
        // console.log(leftVal, t)//10 20

        function fn({ a, b = '默認(rèn)值' }) {
            console.log(a)//1
        }
        fn({
            a: 1,
            b: undefined
        })
13.set數(shù)據(jù)結(jié)構(gòu)(可用于快速去重)
set數(shù)據(jù)結(jié)構(gòu):
    類似數(shù)組趁曼,但是里面不能有重復(fù)值

let arr  = ['a','b','a'];

let arr = new Array();

set用法:
    let setArr = new Set(['a','b']);

    setArr.add('a');   往setArr里面添加一項(xiàng)
    setArr.delete('b'); 刪除一項(xiàng)
    setArr.has('a') 判斷setArr里面有沒(méi)有此值
    setArr.size 個(gè)數(shù)

    setArr.clear(); 清空

14.Spread Operator 展開(kāi)運(yùn)算符(...)
... [1,2,3,4]  ->  1,2,3,4,5
... 1,2,3,4,5  ->  [1,2,3,4,5]
15.字符串新增方法

https://www.cnblogs.com/weimingmei/p/11488458.html
1、String.fromCodePoint()
2棕洋、String.raw()
3挡闰、codePointAt()
4、normalize()
5掰盘、includes(), startsWith(), endsWith()
6摄悯、repeat()
7、padStart()愧捕,padEnd()
8奢驯、trimStart(),trimEnd()
9次绘、matchAll()

關(guān)于字符串一些東西:
字符串查找:
        str.indexOf(要找的東西)   返回索引(位置) 叨橱,沒(méi)找到返回-1
        str.includes(要找的東西)   返回值  true/false

        判斷瀏覽器:  includes

        http://www.xxx.xx

        字符串是否以誰(shuí)開(kāi)頭:
            str.startsWith(檢測(cè)東西)

            檢測(cè)地址
        字符串是否以誰(shuí)結(jié)尾:
            str.endsWith(檢測(cè)東西)

            .png

        重復(fù)字符串:
            str.repeat(次數(shù));
填充字符串:
        str.padStart(整個(gè)字符串長(zhǎng)度, 填充東西)   往前填充
        str.padEnd(整個(gè)字符串長(zhǎng)度, 填充東西)    往后填充

        str.padStart(str.length+padStr.length, padStr)
16.聲明類與繼承:class典蜕、extend断盛,ES6 class與ES5 function區(qū)別及聯(lián)系
image.png

區(qū)別
https://blog.csdn.net/u012657197/article/details/77542404

17.symbol應(yīng)用
數(shù)據(jù)類型:
    number罗洗、string、boolean钢猛、Object伙菜、undefined、function

    用typeof檢測(cè)出來(lái)數(shù)據(jù)類型: symbol

    new Number(12)
    new String()
    new Array()

symbol  使用情況一般

定義:
    let syml = Symbol('aaa');

注意:
1. Symbol 不能new
2. Symbol() 返回是一個(gè)唯一值坊間傳說(shuō), 做一個(gè)key命迈,定義一些唯一或者私有一些東
3. symbol是一個(gè)單獨(dú)數(shù)據(jù)類型贩绕,就叫 symbol, 基本類型
4. 如果symbol作為key,用for in循環(huán)壶愤,出不來(lái)
5.Symbol值作為對(duì)象屬性時(shí)淑倾,不能使用點(diǎn)運(yùn)算符。


json  ->  for in
18.es6和es7中新增加了什么

ES2016(es7)添加了兩個(gè)小的特性來(lái)說(shuō)明標(biāo)準(zhǔn)化過(guò)程:
數(shù)組includes()方法征椒,用來(lái)判斷一個(gè)數(shù)組是否包含一個(gè)指定的值娇哆,根據(jù)情況,如果包含則返回true勃救,否則返回false碍讨。
a ** b指數(shù)運(yùn)算符,它與 Math.pow(a, b)相同蒙秒。


image.png
19.ES6怎么編譯成ES5,css-loader原理,過(guò)程

Babel 是一個(gè) JavaScript 編譯器勃黍,Babel 是一個(gè)工具鏈,主要用于將 ECMAScript 2015+ 版本的代碼轉(zhuǎn)換為向后兼容的 JavaScript 語(yǔ)法晕讲,以便能夠運(yùn)行在當(dāng)前和舊版本的瀏覽器或其他環(huán)境中覆获。Webpack也有自動(dòng)編譯轉(zhuǎn)換能力。
①引入腳本babel庫(kù)②如下

image.png

css-loader原理,過(guò)程
loader 用于對(duì)模塊的源代碼進(jìn)行轉(zhuǎn)換瓢省。loader 可以使你在 import 或"加載"模塊時(shí)預(yù)處理文件弄息。因此,loader 類似于其他構(gòu)建工具中“任務(wù)(task)”净捅,并提供了處理前端構(gòu)建步驟的強(qiáng)大方法疑枯。css-loader是分析各個(gè)css文件的關(guān)系并合并成一個(gè)css。
關(guān)于es6及以上的js編譯成es5

20.ES6轉(zhuǎn)成ES5的常見(jiàn)例子

https://www.cnblogs.com/slongs/p/11238574.html

21.使用解構(gòu)蛔六,實(shí)現(xiàn)兩個(gè)變量的值的交換
let [a,b]=[b,a]
22.利用數(shù)組推導(dǎo)荆永,計(jì)算出數(shù)組 [1,2,3,4] 每一個(gè)元素的平方并組成新的數(shù)組
    var arr1 = [1, 2, 3, 4];
    var arr2 = arr1.map(i => i * i)
    console.log(arr2);
23.map和set有沒(méi)有用過(guò),如何實(shí)現(xiàn)一個(gè)數(shù)組去重国章,map數(shù)據(jù)結(jié)構(gòu)有什么優(yōu)點(diǎn)具钥?ES6的Set內(nèi)部實(shí)現(xiàn)

Map 對(duì)象
Map 對(duì)象保存鍵值對(duì)。任何值(對(duì)象或者原始值) 都可以作為一個(gè)鍵或一個(gè)值液兽。

Maps 和 Objects 的區(qū)別

1骂删、一個(gè) Object 的鍵只能是字符串或者 Symbols掌动,但一個(gè) Map 的鍵可以是任意值。
2宁玫、Map 中的鍵值是有序的(FIFO 原則)粗恢,而添加到對(duì)象中的鍵則不是。
3欧瘪、Map 的鍵值對(duì)個(gè)數(shù)可以從 size 屬性獲取眷射,而 Object 的鍵值對(duì)個(gè)數(shù)只能手動(dòng)計(jì)算。
4佛掖、Object 都有自己的原型妖碉,原型鏈上的鍵名有可能和你自己在對(duì)象上的設(shè)置的鍵名產(chǎn)生沖突。

for…of

var myMap = new Map();
myMap.set(0, "zero");
myMap.set(1, "one");
 
// 將會(huì)顯示兩個(gè) log芥被。 一個(gè)是 "0 = zero" 另一個(gè)是 "1 = one"
for (var [key, value] of myMap) {
  console.log(key + " = " + value);
}
for (var [key, value] of myMap.entries()) {
  console.log(key + " = " + value);
}
/* 這個(gè) entries 方法返回一個(gè)新的 Iterator 對(duì)象欧宜,它按插入順序包含了 Map 對(duì)象中每個(gè)元素的 [key, value] 數(shù)組。 */
 
// 將會(huì)顯示兩個(gè)log拴魄。 一個(gè)是 "0" 另一個(gè)是 "1"
for (var key of myMap.keys()) {
  console.log(key);
}
/* 這個(gè) keys 方法返回一個(gè)新的 Iterator 對(duì)象冗茸, 它按插入順序包含了 Map 對(duì)象中每個(gè)元素的鍵。 */
 
// 將會(huì)顯示兩個(gè)log羹铅。 一個(gè)是 "zero" 另一個(gè)是 "one"
for (var value of myMap.values()) {
  console.log(value);
}
/* 這個(gè) values 方法返回一個(gè)新的 Iterator 對(duì)象蚀狰,它按插入順序包含了 Map 對(duì)象中每個(gè)元素的值。 */

forEach()

var myMap = new Map();
myMap.set(0, "zero");
myMap.set(1, "one");
 
// 將會(huì)顯示兩個(gè) logs职员。 一個(gè)是 "0 = zero" 另一個(gè)是 "1 = one"
myMap.forEach(function(value, key) {
  console.log(key + " = " + value);
}, myMap)

Map 與 Array的轉(zhuǎn)換

var kvArray = [["key1", "value1"], ["key2", "value2"]];
 
// Map 構(gòu)造函數(shù)可以將一個(gè) 二維 鍵值對(duì)數(shù)組轉(zhuǎn)換成一個(gè) Map 對(duì)象
var myMap = new Map(kvArray);
 
// 使用 Array.from 函數(shù)可以將一個(gè) Map 對(duì)象轉(zhuǎn)換成一個(gè)二維鍵值對(duì)數(shù)組
var outArray = Array.from(myMap);

Set 對(duì)象
Set 對(duì)象允許你存儲(chǔ)任何類型的唯一值麻蹋,無(wú)論是原始值或者是對(duì)象引用。

Set 中的特殊值
Set 對(duì)象存儲(chǔ)的值總是唯一的焊切,所以需要判斷兩個(gè)值是否恒等扮授。有幾個(gè)特殊值需要特殊對(duì)待:

+0 與 -0 在存儲(chǔ)判斷唯一性的時(shí)候是恒等的,所以不重復(fù)专肪;
undefined 與 undefined 是恒等的刹勃,所以不重復(fù);
NaN 與 NaN 是不恒等的嚎尤,但是在 Set 中只能存一個(gè)荔仁,不重復(fù)。
let mySet = new Set();

mySet.add(1); // Set(1) {1}
mySet.add(5); // Set(2) {1, 5}
mySet.add(5); // Set(2) {1, 5} 這里體現(xiàn)了值的唯一性
mySet.add("some text"); 
// Set(3) {1, 5, "some text"} 這里體現(xiàn)了類型的多樣性
var o = {a: 1, b: 2}; 
mySet.add(o);
mySet.add({a: 1, b: 2}); 
// Set(5) {1, 5, "some text", {…}, {…}} 
// 這里體現(xiàn)了對(duì)象之間引用不同不恒等芽死,即使值相同乏梁,Set 也能存儲(chǔ)

類型轉(zhuǎn)換

// Array 轉(zhuǎn) Set
var mySet = new Set([“value1”, “value2”, “value3”]);
// 用…操作符,將 Set 轉(zhuǎn) Array
var myArray = […mySet];
String
// String 轉(zhuǎn) Set
var mySet = new Set('hello'); // Set(4) {"h", "e", "l", "o"}
// 注:Set 中 toString 方法是不能將 Set 轉(zhuǎn)換成 String

數(shù)組去重

var mySet = new Set([1, 2, 3, 4, 4]);
[...mySet]; // [1, 2, 3, 4]

map優(yōu)點(diǎn)
Map保存[key-value]值关贵,value可多值遇骑。

ES6的Set內(nèi)部實(shí)現(xiàn)
https://www.cnblogs.com/hui-fly/p/9459152.html

24.取數(shù)組的最大值(ES5、ES6)
// ES5 的寫法
Math.max.apply(null, [14, 3, 77, 30]);
 
// ES6 的寫法
Math.max(...[14, 3, 77, 30]);
 
// reduce
[14,3,77,30].reduce((accumulator, currentValue)=>{
    return accumulator = accumulator > currentValue ? accumulator : currentValue
});
25.const obj 的屬性如何不可變

const定義的基本數(shù)據(jù)類型的變量確實(shí)不能修改揖曾。
因?yàn)閷?duì)象是引用類型的落萎,保存的僅是對(duì)象的指針亥啦,這就意味著,const僅保證指針不發(fā)生改變练链,修改對(duì)象的屬性不會(huì)改變對(duì)象的指針翔脱,所以是被允許的。也就是說(shuō)const定義的引用類型只要指針不發(fā)生改變兑宇,其他的不論如何改變都是允許的碍侦。我們?cè)囍薷囊幌轮羔槪孭指向一個(gè)新對(duì)象隶糕,結(jié)果如下圖:

image

即使對(duì)象的內(nèi)容沒(méi)發(fā)生改變,指針改變也是不允許的站玄。

26.ES6新的特性有哪些枚驻?x4

1、let const命令
2株旷、解構(gòu)賦值
3再登、字符串方法模板字符串
4、默認(rèn)函數(shù)晾剖、剩余函數(shù)锉矢、箭頭函數(shù)
5、Symbol
6齿尽、Set和Map
7沽损、模塊化
8、promise
9循头、class繼承
10绵估、數(shù)組的擴(kuò)展

27.Promise對(duì)象
image.png
28.用es6 promise實(shí)現(xiàn)封裝XMLHttpRequest

只需創(chuàng)建一個(gè)Promise對(duì)象,調(diào)用它的resolve()和reject()以及then()方法卡骂,then()里面也可以寫箭頭函數(shù)国裳;

function verifyIdCard(idCardOptions) {
    let options = {
        // url: config.idCardKey.idCardHost + '?idCard=' + idCardOptions.idCard + '&name=' + idCardOptions.name,
        url: 'https://idcert.market.alicloudapi.com/idcard',
        method: 'GET', 
        qs: {
            idCard: idCardOptions.idCard,
            name: idCardOptions.name
        },
        headers: { 
            'cache-control': 'no-cache',
            Authorization: 'APPCODE ' + config.idCardKey.idCardAppCode,
            'Content-Type': 'application/json'
        },
        json: true
    };

    console.info(options)
    return new Promise((resolve, reject) => {
        request(options, (error, response, body) => {
            if (!error && (response.statusCode === 200 || response.statusCode === 304)) {
                let IdCardInfo = {
                    reqInfo: idCardOptions,
                    resInfo: body
                }
                console.info(IdCardInfo)
                let idCardModel = new IdCardModel(IdCardInfo);
                idCardModel.save();
                resolve(body);
            } else {
                reject(error);
            }
        })
    })
}

29.generator(異步編程、yield全跨、next()缝左、await 、async)

Generator 函數(shù)浓若,可以通過(guò) yield 關(guān)鍵字渺杉,把函數(shù)的執(zhí)行流掛起,為改變執(zhí)行流程提供了可能七嫌,從而為異步編程提供解決方案少办。Generator 有兩個(gè)區(qū)分于普通函數(shù)的部分:一是在 function 后面,函數(shù)名之前有個(gè) * 诵原;函數(shù)內(nèi)部有 yield 表達(dá)式英妓。其中 * 用來(lái)表示函數(shù)為 Generator 函數(shù)挽放,yield 用來(lái)定義函數(shù)內(nèi)部的狀態(tài)。

function* sendParameter(){
    console.log("strat");
    var x = yield '2';
    console.log("one:" + x);
    var y = yield '3';
    console.log("two:" + y);
    console.log("total:" + (x + y));
}

var sendp1 = sendParameter();
sendp1.next();
// strat
// {value: "2", done: false}
sendp1.next();
// one:undefined
// {value: "3", done: false}
sendp1.next();
// two:undefined
// total:NaN
// {value: undefined, done: true}
var sendp2 = sendParameter();
sendp2.next(10);
// strat
// {value: "2", done: false}
sendp2.next(20);
// one:20
// {value: "3", done: false}
sendp2.next(30);
// two:30
// total:50
// {value: undefined, done: true}
}

一般情況下蔓纠,next 方法不傳入?yún)?shù)的時(shí)候辑畦,yield 表達(dá)式的返回值是 undefined 。當(dāng) next 傳入?yún)?shù)的時(shí)候腿倚,該參數(shù)會(huì)作為上一步y(tǒng)ield的返回值纯出。yield* 表達(dá)式表示 yield 返回一個(gè)遍歷器對(duì)象,用于在 Generator 函數(shù)內(nèi)部敷燎,調(diào)用另一個(gè) Generator 函數(shù)暂筝。

async
async 是 ES7 才有的與異步操作有關(guān)的關(guān)鍵字,和 Promise 硬贯, Generator 有很大關(guān)聯(lián)的焕襟。async 函數(shù)返回一個(gè) Promise 對(duì)象,可以使用 then 方法添加回調(diào)函數(shù)饭豹。

async function helloAsync(){
    return "helloAsync";
  }
  
console.log(helloAsync())  // Promise {<resolved>: "helloAsync"}
 
helloAsync().then(v=>{
   console.log(v);         // helloAsync
})

await
await 操作符用于等待一個(gè) Promise 對(duì)象, 它只能在異步函數(shù) async function 內(nèi)部使用鸵赖。返回 Promise 對(duì)象的處理結(jié)果。如果等待的不是 Promise 對(duì)象拄衰,則返回該值本身它褪。如果一個(gè) Promise 被傳遞給一個(gè) await 操作符,await 將等待 Promise 正常處理完成并返回其處理結(jié)果翘悉。

function testAwait (x) {
  return new Promise(resolve => {
    setTimeout(() => {
      resolve(x);
    }, 2000);
  });
}
 
async function helloAsync() {
  var x = await testAwait ("hello world");
  console.log(x); 
}
helloAsync ();
// hello world

正常情況下茫打,await 命令后面是一個(gè) Promise 對(duì)象,它也可以跟其他值镐确,如字符串包吝,布爾值,數(shù)值以及普通函數(shù)源葫。await針對(duì)所跟不同表達(dá)式的處理方式:Promise 對(duì)象:await 會(huì)暫停執(zhí)行诗越,等待 Promise 對(duì)象 resolve,然后恢復(fù) async 函數(shù)的執(zhí)行并返回解析值息堂。非 Promise 對(duì)象:直接返回對(duì)應(yīng)的值嚷狞。


image.png
image.png
image.png
image.png
image.png
image.png
image.png
image.png
image.png
image.png
image.png
image.png
image.png
image.png
image.png
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市荣堰,隨后出現(xiàn)的幾起案子床未,更是在濱河造成了極大的恐慌,老刑警劉巖振坚,帶你破解...
    沈念sama閱讀 222,252評(píng)論 6 516
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件薇搁,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡渡八,警方通過(guò)查閱死者的電腦和手機(jī)啃洋,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,886評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門传货,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人宏娄,你說(shuō)我怎么就攤上這事问裕。” “怎么了孵坚?”我有些...
    開(kāi)封第一講書人閱讀 168,814評(píng)論 0 361
  • 文/不壞的土叔 我叫張陵环凿,是天一觀的道長(zhǎng)蔚舀。 經(jīng)常有香客問(wèn)我钞馁,道長(zhǎng)坪稽,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書人閱讀 59,869評(píng)論 1 299
  • 正文 為了忘掉前任逗堵,我火速辦了婚禮秉氧,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘蜒秤。我一直安慰自己,他們只是感情好亚斋,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,888評(píng)論 6 398
  • 文/花漫 我一把揭開(kāi)白布作媚。 她就那樣靜靜地躺著,像睡著了一般帅刊。 火紅的嫁衣襯著肌膚如雪纸泡。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書人閱讀 52,475評(píng)論 1 312
  • 那天赖瞒,我揣著相機(jī)與錄音女揭,去河邊找鬼。 笑死栏饮,一個(gè)胖子當(dāng)著我的面吹牛吧兔,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播袍嬉,決...
    沈念sama閱讀 41,010評(píng)論 3 422
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼境蔼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了伺通?” 一聲冷哼從身側(cè)響起箍土,我...
    開(kāi)封第一講書人閱讀 39,924評(píng)論 0 277
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎罐监,沒(méi)想到半個(gè)月后吴藻,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,469評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡弓柱,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,552評(píng)論 3 342
  • 正文 我和宋清朗相戀三年沟堡,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了侧但。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,680評(píng)論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡弦叶,死狀恐怖俊犯,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情伤哺,我是刑警寧澤燕侠,帶...
    沈念sama閱讀 36,362評(píng)論 5 351
  • 正文 年R本政府宣布,位于F島的核電站立莉,受9級(jí)特大地震影響绢彤,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜蜓耻,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,037評(píng)論 3 335
  • 文/蒙蒙 一茫舶、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧刹淌,春花似錦饶氏、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 32,519評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至蔼卡,卻和暖如春喊崖,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背雇逞。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 33,621評(píng)論 1 274
  • 我被黑心中介騙來(lái)泰國(guó)打工荤懂, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人塘砸。 一個(gè)月前我還...
    沈念sama閱讀 49,099評(píng)論 3 378
  • 正文 我出身青樓节仿,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親谣蠢。 傳聞我的和親對(duì)象是個(gè)殘疾皇子粟耻,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,691評(píng)論 2 361

推薦閱讀更多精彩內(nèi)容