面試題裡的那些各種手寫

火貓裸輝耀發表於2019-04-10

最近準備初級前端面試,發現有很多手寫實現什麼的,例如什麼手寫實現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(//.......)
  }//大概是這樣的意思,寫法根據陣列的不同可能會有所改變
複製程式碼

這期間會不斷更新並修改,您如果有更好的寫法或者新的思路,也希望可以說明交流

相關文章