前端面試之ES6篇(高產似母豬)

B_Cornelius發表於2017-09-25

這也是前端面試經常詢問的問題,經常問你es6出現了哪些新的特性,平時又使用過那些。在編寫此教程的時候,第一句話往往就是面試常常問到的地方,然後後面就是他的詳細解釋,面試要求的內容我會用*標記出來。寫技術文件是真的累啊,雖然是看別人的文件,但是你得看很多,而且還得自己總結啊。所以說要是覺得對你有用還是幫我點個star吧https://github.com/skychenbo

1、箭頭函式需要注意的地方
2、ES6 let、const
3、set資料結構
4、promise物件的用法,手寫一個promise
5、class的理解
6、模版語法的理解
7、rest引數
8、	module體系
複製程式碼

箭頭函式需要注意的地方

*當要求動態上下文的時候,就不能夠使用箭頭函式。也就是this的固定化 1、在使用=>定義函式的時候,this的指向是定義時所在的物件,而不是使用時所在的物件 2、不能夠用作建構函式,這就是說,不能夠使用new命令,否則就會丟擲一個錯誤 3、不能夠使用arguments物件 4、不能使用yield命令 這是一道當年很困惑我的一道題不知道你在第一眼能不能看出其結果,this的指向總是讓人困擾,但是有了=>以後媽媽再也不用擔心你使用this了

class Animal {
	constructor(){
		this.type = 'animal'
	}
	says(say) {
		setTimeout(function () {
			console.log(this.type + 'says' + say)
		},1000)
	}
}
var animal = new Animal()
animal.says('hi') // undefined says hi
複製程式碼

我們再來看看=>的情況

class Animal() {
	constructor() {
		this.type = 'animal'
	}
	says(say) {
		setTimeout(() => {
			console.log(this.type + ' says ' + say)
		}, 1000)
	}
}
var animal = new Animal()
animal.says('hi') // animal says hi
複製程式碼

ES6 let、const *let是更完美的var,不是全域性變數,具有塊級函式作用域,大多數情況不會發生變數提升。const定義常量值,不能夠重新賦值,如果值是一個物件,可以改變物件裡邊的屬性值 let 1、let宣告的變數具有塊級作用域 2、let宣告的變數不能通過window.變數名進行訪問 3、形如for(let x..)的迴圈是每次迭代都為x建立新的繫結 下面是var帶來的不合理場景

var a = []
for (var i = 0; i < i; i++) {
	a[i] = function () {
		console.log(i)
	}
}
a[5]() // 10
複製程式碼

在上述程式碼中,變數i是var宣告的,在全域性範圍類都有效。所以每一次迴圈,新的i值都會覆蓋舊值,導致最後輸出都是10 而如果對迴圈使用let語句的情況,那麼每次迭代都是為x建立新的繫結程式碼如下

var a = []
for (let i = 0; i < 10; i++) {
	a[i] = function () {
		console.log(i)
	}
}
a[5]() // 5
複製程式碼

當然除了這種方式讓陣列中的各個元素分別是不同的函式,我們還可以採用閉包和立即函式兩種方法 這是閉包的方法

function showNum(i) {
	return function () {
		console.log(i)
	}
}
var a = []
for (var i = 0; i < 5; i++) {
	a[i] = showNum(i)
}
複製程式碼

這是立即函式的方法

var a = []
for (var i = 0; i < 5; i++) {
	a[i] = (function (i) {
		return function () {
			console.log(i)
		}
	})(i)
}
a[2]()
複製程式碼

Set資料結構

*es6方法,Set本身是一個建構函式,它類似於陣列,但是成員值都是唯一的

const set = new Set([1,2,3,4,4])
[...set] // [1,2,3,4]
Array.from(new Set())是將set進行去重
複製程式碼

promise物件的用法,手寫一個promise

promise是一個建構函式,下面是一個簡單例項

var promise = new Promise((resolve,reject) => {
	if (操作成功) {
		resolve(value)
	} else {
		reject(error)
	}
})
promise.then(function (value) {
	// success
},function (value) {
	// failure
})
複製程式碼

Class的講解

*class語法相對原型、建構函式、繼承更接近傳統語法,它的寫法能夠讓物件原型的寫法更加清晰、物件導向程式設計的語法更加通俗 這是class的具體用法

class Animal {
	constructor () {
		this.type = 'animal'
	}
	says(say) {
		console.log(this.type + 'says' + say)
	}
}
 let animal = new Animal()
 animal.says('hello') // animal says hello

 class Cat extends Animal {
 	constructor() {
 		super()
 		this.type = 'cat'
 	}
 }
 let cat = new Cat()
 cat.says('hello') // cat says hello
複製程式碼

可以看出在使用extend的時候結構輸出是cat says hello 而不是animal says hello。說明contructor內部定義的方法和屬性是例項物件自己的,不能通過extends 進行繼承。在class cat中出現了super(),這是什麼呢 在ES6中,子類的建構函式必須含有super函式,super表示的是呼叫父類的建構函式,雖然是父類的建構函式,但是this指向的卻是cat Object.assign 方法 var n = Object.assign(a,b,c)向n中新增a,b,c的屬性

模版語法

*就是這種形式${varible},在以往的時候我們在連線字串和變數的時候需要使用這種方式'string' + varible + 'string'但是有了模版語言後我們可以使用string${varible}string這種進行連線

rest引數

*es6引入rest引數,用於獲取函式的多餘引數,這樣就不需要使用arguments物件了 ex:

function add(...values) {
	let sum = 0
	for(var val of values) {
		sum += val
	}
	return sum
}
複製程式碼

module體系

*歷史上js是沒有module體系,無法將一個大程式拆分成一些小的程式。在es6之前,有commonJs,AMD兩種 CommonJS是如何書寫的呢

const animal = require('./content.js')
	// content.js
	module.exports = 'a cat'
複製程式碼

require.js是這樣做的 // content.js

define('content.js', function () {
	return 'A cat'
})

require(['./content.js'], function (animal) {
	console.log(animal) // a cat
})
複製程式碼

ES6的語法(在我用的vue中,就使用的是這個)

import animal from './content'
// content.js
export default 'a cat'
複製程式碼

es6 import的其他用法 在vue中可以 import animal from './content' animal這個值可以根據你的喜歡而改變,但是有一個問題就是如果一旦引入的是函式或者變數時,你就必須和content中的名字保持一致,可以參照 import { say, type } from './content' 常用的還有一種寫法 import * as content from './content'
這種寫法就是表示所有的輸出值都在這個物件上

相關文章