最近準備初級前端面試,發現有很多手寫實現什麼的,例如什麼手寫實現bind,promise。手寫ajax,手寫一些演算法。 翻閱了很多書籍和部落格。
這裡做一個總結改進,算是對我後面大概為期一個月找工作的準備。
手寫實現bind()
Function.prototype._bind = function (context) {
var self = this;
var args = Array.prototype.slice.call(arguments, 1);
var fBind = function () {
var bindArgs = Array.prototype.slice.call(arguments);
return self.apply(this instanceof fBind ? this : context, args.concat(bindArgs));
}
fBind.prototype = self.prototype&&Object.create(self.prototype)
return fBind;
}
複製程式碼
簡單的說明:
- 這裡之所以傳參的時候需要兩個陣列,是因為考慮到用
new
以建構函式的形式呼叫硬繫結函式的情況。 - 這樣子就需要繼承之前函式的方法,
fBind.prototype = self.prototype&&Object.create(self.prototype)
,同時也可以用Object.setPrototypeOf(fBind.prototype,self.prototype)
。 考慮到存在undefined
的情況,前面加一個判斷self.prototype&&.....
- 關於
apply
的第一個引數,如果考慮到之前的情況,是不能傳入context
的,這需要做一個判斷。 像是下面的情況
function Foo(price){
this.price =price
this.fn = ()=>{
console.log('hi fn')
}
console.log(this.name)
}
Foo.prototype.sayMyName = function(){
console.log(this.name)
}
var Obj1 = {
name:'obj1'
}
var b =Foo._bind(Obj1)
var c = new b(1000)
c.name = 'i am c'
c.sayMyName()
複製程式碼
這裡的this
的指向就是c
,它指向例項物件本身。
後面以這道題為引線面試官可能會追問:
- 什麼是執行上下文
- this的判斷
- call,bind的區別
手寫一個函式實現斐波那契數列
首先拷一個阮神在他es6教程裡的一個寫法。
function* fibonacci() {
let [prev, curr] = [0, 1];
for (;;) {
yield curr;
[prev, curr] = [curr, prev + curr];
}
}
for (let n of fibonacci()) {
if (n > 1000) break;
console.log(n);
}
複製程式碼
更精簡的
const feibo= max=>{
let [a,b,i]= [0,1,1]
while(i++<=max) {
[a,b] = [b,a + b ]
console.log(b)
}
return a
}
複製程式碼
相對是非常簡單的,感覺也不會多問啥,就不多說了。
手寫一個簡單的ajax
let xhr = new XMLHttpRequest
xhr.open('get', url, true)
xhr.onreadystatechange = function(){
if(this.readyState === 4){
if(this.status >= 200 &&this.status<300){
conso.log('成功')
}else{
consol.log('失敗')
}
}
}
xhr.onerror = function(e) {
console.log('連線失敗')
}
xhr.send()
複製程式碼
大概是這麼個意思就差不多了,順勢可能會問一些狀態碼和狀態值的問題,或者直接問到關於http上面的問題。
原型繼承
function inherit(supertype,subtype){
Object.setPrototypeOf(subtype.prototype,supertype.prototype)
subtype.prototype.constructor = subtype
}
function Car(name,power){
this.name=name
this.power = power
}
Car.prototype.showPower = function(){
console.log(this.power)
}
function Changan(price,name,power){
this.price = price
Car.call(this,name,power)
}
inherit(Car,Changan)
Changan.prototype.showName = function(){
console.log(this.name)
}
var star = new Changan(100000,'star',500)
star.showPower()
複製程式碼
防抖與節流
function debounce(fn,duration){
var timer
window.clearTimeout(timer)
timer = setTimeout(()=>{
fn.call(this)
},duration)
}
function throttle(fn,duration){
let canIRun
if(!canIRun)return
fn.call(this)
canIRun = false
setTimeout(()=>{
canIRun = true
},duration)
}
複製程式碼
陣列去重
我一般就用這兩種,大部分情況都能應付了。
[...new Set(array)]
複製程式碼
//hash
function unique(array) {
const object = {}
array.map(number=>{
object[number] = true
})
return Object.keys(object).map(//.......)
}//大概是這樣的意思,寫法根據陣列的不同可能會有所改變
複製程式碼
這期間會不斷更新並修改,您如果有更好的寫法或者新的思路,也希望可以說明交流