1. 程式人生 > 其它 >面試中常問到的ES6

面試中常問到的ES6

技術標籤:面試題ES6javascriptjs

目的

1、熟練使用ES6語言
2、Promise物件

什麼是ES6

ES6:全稱ECMAScript 6.0 ,是JavaScript的下一個版本標準,2015.06發版。
ES6主要是為了解決ES5的先天不足,比如JavaScript裡並沒有類的概念

Let、const和var的區別

Es6新增了let和const來宣告變數,主要是解決var宣告變數所造成的困擾和問題:

  • var 不能用於定義常量
  • var 可以重複宣告變數
  • var 存在變數提升
  • var 不支援塊級作用域

let 和const解決了以上問題如下:

  • 不可以重複宣告變數
let site =
'itLike'; let site = 'itLike'; console.log(site);
  • 不存在變數提升
console.log(site);

let site = 'itLike';
  • 可以定義常量
const E = 2.718;

E = 2.71;

console.log(E);

//  引用型別
const LK = {

   name:'itLike',

   intro: '喜歡IT, 就上撩課(itLike.com)'

};

LK.name = '撩課';
console.log(LK);
  • 塊級作用域
    如果用var定義變數,變數是通過函式或者閉包擁有作用域;但,現在用let定義變數,不僅僅可以通過函式/閉包隔離,還可以通過塊級作用域隔離。
    塊級作用域用一組大括號定義一個塊,使用 let 定義的變數在大括號的外部是訪問不到的,此外,let宣告的變數不會汙染全域性作用域。
{let site = 'itLike';}

console.log(site);

if(1){  let str = '04'; }

console.log(str);

解構賦值

解構賦值是對賦值運算的擴充套件
他是一種針對陣列或物件進行模式匹配,然後對其中的變數進行賦值。
在程式碼書寫上簡潔易讀,語義更加清晰明瞭;也方便了複雜物件中資料欄位獲取。

  • 構的源,解構賦值表示式的右邊部分。
  • 解構的目標,解構賦值表示式的左邊部分。
    ## 變數解構賦值(陣列解構)
let
nameArr = ['撩課', '小撩', '小煤球']; let name1 = nameArr[0]; let name2 = nameArr[1]; let name3 = nameArr[2]; // 解構寫法 let [name1, name2, name3] = nameArr; console.log(name1, name2, name3);

## 變數解構賦值(物件解構)

//  寫法1

let {name, age, sex}

 = {name: '小煤球', age: 1, sex: '公'};

// 結果: 小煤球 1 公

console.log(name, age, sex);

//  寫法2: 解構重新命名

let {name: lkName, age: lkAge, sex: lkSex}

= {name: '小煤球', age: 1, sex: '公'};

// 結果: 小煤球 1 公

console.log(lkName, lkAge, lkSex);  

//  寫法3: 可以設定預設值

let {name, age, sex = '公'}

= {name: '小煤球', age: 1};

console.log(sex);  // 公


//  寫法4:省略解構

let [, , sex] = ['小煤球', 1, '公 '];

console.log(sex);

字串、正則、數值、函式、陣列、物件的擴充套件、箭頭函式和普通函式區別

模板字串
模板字串用反引號()包含,變數用${}括起來;在開發中使用是非常靈活的

 let name = '小煤球';
 let sex = '公';
 let result = `我叫 ${name} , 我是 ${sex}`;
 console.log(result);

字串擴充套件方法

  • startsWith()
    判斷字串是否以xx開頭;
let url = 'http://www.itlike.com';

console.log(url.startsWith('http'));  // true
  • endsWith()
    判斷字串是否以xx結尾
let file = 'index.html';

console.log(file.endsWith('html'));  // true
  • includes
    判斷字串中是否包含xx;
let str = 'liaoke';

console.log(str.includes('ao')); // true
  • repeat()
    拷貝n份
let title = '撩課線上';

console.log(title.repeat(100));
  • padStart() / padEnd()
    padStart()用於頭部補全,
    padEnd()用於尾部補全;
    第一個引數用來指定字串的最小長度,
    第二個引數是用來補全的字串。
//  "2030111111"

let y1 = '2030'.padEnd(10, '1');

//   "2030-11-22"

let y2 = '11-22'.padStart(10, '2030-MM-DD');  

console.log(y1, y2);

延展操作符

  • 延展陣列
let arr1 = [ 'a', 'b', 'c'];
let arr2 = [1, 2, 3];
let result = [...arr1, ...arr2];
console.log(result);
 //  [ "a", "b", "c", 1, 2, 3 ]
  • 延展物件
let smallDog = {name:'小煤球', age: 1};
let bigDog = {name: 'Python', age: 2};
let dog = {...smallDog, ...bigDog};
console.log(dog);  
// {name: "Python", age: 2}

注意:如果物件中的屬性一致,會被覆蓋

  • 開發應用場景
function getMinValue() {
     console.log(Math.min(...arguments));
}
getMinValue(1, -99, 22, 10, 9); // -99

數值擴充套件

  • 常量
    Number.EPSILON ,屬性表示 1 與大於 1 的最小浮點數之間的差。
    它的值接近於 2.2204460492503130808472633361816E-16,或者 2-52。
    測試數值是否在誤差範圍內:
0.1 + 0.2 === 0.3; // false
// 在誤差範圍內即視為相等
var equal = (Math.abs(0.1 - 0.3 + 0.2) < Number.EPSILON); // true
  • 最大安全整數
    安全整數:Number.MAX_SAFE_INTEGER
    安全整數表示在 JavaScript 中能夠精確表示的整數,安全整數的範圍在 2 的 -53 次方到 2 的 53 次方之間(不包括兩個端點),超過這個範圍的整數無法精確表示。
    最大安全整數
    安全整數範圍的上限,即 2 的 53 次方減 1 。
  • 最小安全整數
    安全整數範圍的下限,即 2 的 53 次方減 1 的負數。
    Number.MIN_SAFE_INTEGER

Math物件的擴充套件
Es6在Math物件上新增了17個屬性相關的靜態方法,這些方法只能在math中呼叫

  • 普通計算
    math.cdrt
    用於計算一個數的立方根
Math.cbrt(1);  // 1
Math.cbrt(0);  // 0
Math.cbrt(-1); // -1
// 會對非數值進行轉換
Math.cbrt('1'); // 1

// 非數值且無法轉換為數值時返回 NaN
Math.cbrt('hhh'); // NaN

等等…此處需要自己查百度了 哈哈

函式擴充套件

  • 預設引數
    基本用法:
function fn(name,age=17){
 console.log(name+","+age);
}
fn("Amy",18);  // Amy,18
fn("Amy","");  // Amy,
fn("Amy");     // Amy,17

注意點:使用函式預設引數時,不允許有同名引數。
// 不報錯
function fn(name,name){
 console.log(name);
}

// 報錯
//SyntaxError: Duplicate parameter name not allowed in this context
function fn(name,name,age=17){
 console.log(name+","+age);
}
只有在未傳遞引數,或者引數為 undefined 時,才會使用預設引數,null 值被認為是有效的值傳遞。
function fn(name,age=17){
    console.log(name+","+age);
}
fn("Amy",null); // Amy,null

函式引數預設值存在暫時性死區,在函式引數預設值表示式中,還未初始化賦值的引數值無法作為其他引數的預設值。

function f(x,y=x){
    console.log(x,y);
}
f(1);  // 1 1

function f(x=y){
    console.log(x);
}
f();  // ReferenceError: y is not defined
  • 不定引數
    不定引數用來表示不確定引數個數,刑如, …變數名,由…加上一個具名引數識別符號組成。具名引數只能放在引數組的最後,並且有卻只有一個不定引數。
    基本用法:
function f(...values){
    console.log(values.length);
}
f(1,2);      //2
f(1,2,3,4);  //4

箭頭函式
箭頭漢提供了一種更加簡潔的函式書寫方式。基本語法是:
引數=>函式體
function 函式名稱(引數列表){
函式執行體
}
this指標的固化
var函式名稱 = (引數列表)=>{
函式執行體
}

基本用法:

var f = v => v;
//等價於
var f = function(a){
 return a;
}
f(1);  //1

當箭頭函式沒有引數或者有多個引數,要用()括起來.

var f = (a,b) => a+b;
f(6,2);  //8

當箭頭函式函式體有多行語句,用{}包裹起來,表示程式碼塊,當只有一行語句,並且需要返回結果時,可以省略{},結果會自動返回。

var f = (a,b) => {
 let result = a+b;
 return result;
}
f(6,2);  // 8
  • 單行語句返回形式
    當箭頭函式要返回物件的時候,為了區分於程式碼塊,要用()將物件包裹起來
// 報錯
var f = (id,name) => {id: id, name: name};
f(6,2);  // SyntaxError: Unexpected token :

// 不報錯
var f = (id,name) => ({id: id, name: name});
f(6,2);  // {id: 6, name: 2}

注意點:沒有 this、super、arguments 和 new.target 繫結。


var func = () => {
  // 箭頭函式裡面沒有 this 物件,
  // 此時的 this 是外層的 this 物件,即 Window
  console.log(this)
}
func(55)  // Window

var func = () => {    
  console.log(arguments)
}
func(55);  // ReferenceError: arguments is not defined

箭頭函式體中的 this 物件,是定義函式時的物件,而不是使用函式時的物件。

function fn(){
  setTimeout(()=>{
    // 定義時,this 繫結的是 fn 中的 this 物件
    console.log(this.a);
  },0)
}
var a = 20;
// fn 的 this 物件為 {a: 19}
fn.call({a: 18});  // 18

var a = {
  a: 18,
  fn:function(){
    setTimeout(()=>{
      // 定義時,this 繫結的是 fn 中的 this 物件
      console.log(this.a);
    },0)
  }
}

// call():
//將該函式的定義放到傳入的物件下
//呼叫

不可以作為建構函式,也就是不能使用 new 命令,否則會報錯

  • 箭頭函式適合使用的場景
    ES6 之前,JavaScript 的 this 物件一直很令人頭大,回撥函式,經常看到 var self = this 這樣的程式碼,為了將外部 this 傳遞到回撥函式中,那麼有了箭頭函式,就不需要這樣做了,直接使用 this 就行。
// 回撥函式
var Person = {
    'age': 18,
    'sayHello': function () {
      setTimeout(function () {
        console.log(this.age);
      });
    }
};
var age = 20;
Person.sayHello();  // 20

var Person1 = {
    'age': 18,
    'sayHello': function () {
      setTimeout(()=>{
        console.log(this.age);
      });
    }
};
var age = 20;
Person1.sayHello();  // 18

所以,當我們需要維護一個 this 上下文的時候,就可以使用箭頭函式。

陣列擴充套件

  • 陣列建立
    Array.of()
    將引數中所有值作為元素形成陣列
console.log(Array.of(1, 2, 3, 4)); // [1, 2, 3, 4]
// 引數值可為不同型別
console.log(Array.of(1, '2', true)); // [1, '2', true]

// 引數為空時返回空陣列
console.log(Array.of()); // []
  • Array.from()
    將類陣列物件或可迭代物件轉化為陣列。
// 引數為陣列,返回與原陣列一樣的陣列
console.log(Array.from([1, 2])); // [1, 2]

// 引數含空位
console.log(Array.from([1, , 3])); // [1, undefined, 3]

引數

Array.from(arrayLike[, mapFn[, thisArg]])

返回值為轉換後的陣列。

  • arrayLike
    想要轉換的類陣列物件或可迭代物件。
console.log(Array.from([1, 2, 3])); // [1, 2, 3]
  • mapFn
    可選,map 函式,用於對每個元素進行處理,放入陣列的是處理後的元素。
console.log(Array.from([1, 2, 3], (n) => n * 2)); // [2, 4, 6]
  • thisArg
    可選,用於指定 map 函式執行時的 this 物件。
let map = {
    do: function(n) {
        return n * 2;
    }
}
let arrayLike = [1, 2, 3];
console.log(Array.from(arrayLike, function (n){
    return this.do(n);
}),map); // [2, 4, 6]
  • 類陣列物件
    一個類陣列物件必須含有 length 屬性,且元素屬性名必須是數值或者可轉換為數值的字元。
let arr = Array.from({
  0: '1',
  1: '2',
  2: 3,
  length: 3
});
console.log(); // ['1', '2', 3]

// 沒有 length 屬性,則返回空陣列
let array = Array.from({
  0: '1',
  1: '2',
  2: 3,
});
console.log(array); // []

// 元素屬性名不為數值且無法轉換為數值,返回長度為 length 元素值為 undefined 的陣列  
let array1 = Array.from({
  a: 1,
  b: 2,
  length: 2
});
console.log(array1); // [undefined, undefined]
  • 轉換可迭代物件
    轉換map
let map = new Map();
map.set('key0', 'value0');
map.set('key1', 'value1');
console.log(Array.from(map)); // [['key0', 'value0'],['key1',
// 'value1']]
  • 轉換set集合
let arr = [1, 2, 3];
let set = new Set(arr);
console.log(Array.from(set)); // [1, 2, 3]
  • 轉換字串
let str = 'abc';
console.log(Array.from(str)); // ["a", "b", "c"]
  • 擴充套件的方法

查詢
1、find()
查詢陣列中符合條件的元素,若有多個符合條件的元素,則返回第一個元素。
2、findIndex()
查詢陣列中符合條件的元素索引,若有多個符合條件的元素,則返回第一個元素索引。
3、fill()填充
將一定範圍索引的陣列元素內容填充為單個指定的值。
4、entries()遍歷
遍歷鍵值對。
5、keys()
遍歷鍵名。
6、includes()包含
陣列是否包含指定值。
注意:與 Set 和 Map 的 has 方法區分;Set 的 has 方法用於查詢值;Map 的 has 方法用於查詢鍵名
7、flat()巢狀陣列轉一維陣列
8、flatMap()
先對陣列中每個元素進行了的處理,再對陣列執行 flat() 方法。

iterator 和 for …of 迴圈


Iterator 是 ES6 引入的一種新的遍歷機制,迭代器有兩個核心概念:

  • 迭代器是一個統一的介面,它的作用是使各種資料結構可被便捷的訪問,它是通過一個鍵為Symbol.iterator 的方法來實現。
  • 迭代器是用於遍歷資料結構元素的指標(如資料庫中的遊標)。

迭代器是帶有特殊介面的物件。含有一個next()方法,呼叫返回一個包含兩個屬性的物件,分別是value和done,value表示當前位置的值,done表示是否迭代完,當為true的時候,呼叫next就無效了。

ES5中遍歷集合通常都是 for迴圈,陣列還有 forEach 方法,物件就是 for-in,ES6 中又添加了 Map 和 Set,而迭代器可以統一處理所有集合資料的方法。迭代器是一個介面,只要你這個資料結構暴露了一個iterator的介面,那就可以完成迭代。ES6創造了一種新的遍歷命令for…of迴圈,Iterator介面主要供for…of消費。

for遍歷

const fruits = ['apple','coconut','mango','durian'];
//for迴圈陣列,通過下標取得每一項的值
for (let i = 0; i < fruits.length; i++) {
    console.log(fruits[i]);
}

forEach遍歷

//陣列的forEach方法,相對for迴圈語法更簡單
fruits.forEach(fruit => {
    console.log(fruit);
})

//forEach有個問題是不能終止迴圈
fruits.forEach(fruit => {
    if(fruit === 'mango' ){
        break;                        //Illegal break statement
    }
    console.log(fruit);
})

for in 遍歷

//for...in迴圈,遍歷陣列物件的屬性,MDN不推薦使用for...in遍歷陣列
//for...in迴圈會打印出非數字屬性
const fruits = ['apple','coconut','mango','durian'];
fruits.fav = 'my favorite fruit';

for(let index in fruits){
    console.log(fruits[index]);   //...my favorite fruit
}

for of 遍歷

const fruits = ['apple','coconut','mango','durian'];
fruits.fav = 'my favorite fruit';

//ES6中的for...of迴圈,遍歷屬性值
for(let fruit of fruits){
    console.log(fruit);
}

//支援終止迴圈,也不會遍歷非數字屬性
for(let fruit of fruits){
    if(fruit === 'mango' ){
        break;
    }
    console.log(fruit);      //apple coconut durian
}

set和map資料結構


基本用法
set 資料容器 能夠儲存無重複值資料的有序列表

  • 通過 new set() 方法建立容器 通過add() 方法新增
  • set.size獲取儲存的資料的數量
var set = new Set()
set.add(1);
set.add('1');
console.log(set)
console.log(set.size)
  • Set內部使用Object.is()方法來判斷兩個資料項是否相等
  • 利用陣列來構造set 且set 構造器不會存在重複的資料
var set1 = new Set([1,2,3,3,3,3,3,2]) // 結果陣列會去重
  • 可以使用has()方法來判斷某個值是否存在於Set中
  • 使用delete()方法從Set中刪除某個值,或者使用clear()方法從Set中刪除所有值
set1.delete(1)
console.log(set1)
set1.clear()
console.log(set1)
  • forEach 遍歷set
set2.forEach(function(value,key){
	 console.log(value)
	 console.log(key)
 })
  • 將陣列轉換成set 直接將陣列放在new Set()引數中

ES6中提供了Map資料結構,能夠存放鍵值對,其中,鍵的去重是通過Object.is()方法進行比較,鍵的資料型別可以是基本型別資料也可以是物件,而值也可以是任意型別資料。

  • 建立map
var map = new Map()
  • 使用set()方法可以給Map新增鍵值對 ,能夠自動去重,和set原理一樣,新增相同的元素會進行去重處理
var map = new Map()
console.log(map)
map.set('title','baidu')
map.set('year','2018');
  • 通過get()方法可以從Map中提取值,size方法同set一樣,獲取陣列長度
console.log(map.get('year'))    // 2018
console.log(map.size)  // 2
  • 同set一樣,也有 has(),delete(),clear() 方法
map.delete('title');
map.clear();
console.log(map.has('year'));
  • 通過get()方法可以從Map中提取值,size方法同set一樣,獲取陣列長度
console.log(map.get('year'))    // 2018
console.log(map.size)  // 2
  • forEach 遍歷
map.forEach(function(value,key){
console.log(value)  // 值 2018
console.log(key)    // 健 year
})

set和map的區別
都是用來儲存資料用的,但是儲存的資料格式不同
set 直接儲存 任意型別資料
map 儲存資料的時候,必須以key,value的形式,
set 使用forEach 遍歷的時候,key和value值是一樣的
而map 遍歷的時候,key就是存進去的物件的key,value就是存在的值

Promise

首先要明白什麼是Promise
Promise:是非同步程式設計的一種解決方法
如果去使用???

  1. 主要用於非同步計算
    在這裡插入圖片描述
    首先我們先new一個promise(裡面放入兩個引數 resclve和reject)
    在這裡插入圖片描述

  2. 可以將非同步操作佇列化,按照期望的順序進行

  3. 可以在物件之間傳遞promise,幫助我們處理佇列化

  4. 引數分別是:resolve 和 reject
    resolve()的作用是,將promise從未完成變為完成,非同步操作成功時呼叫,結果傳遞出去
    Reject()作用是,將promise狀態從未完成變為失敗,並將非同步操作的錯誤,傳遞出去

promise 有三個狀態:
1、pending ()是 初始狀態
2、fulfilled ()是 操作成功的狀態
3、Rejected()是 操作失敗的狀態
當 promise 狀態發生改變,就會觸發 then()裡的響應函式處理後續步驟
promise 狀態一經改變,不會再變
使用場景:promise封裝api介面

Promise進行非同步操作
解決問題:1.回撥地域問題2.多個併發請求