刷前端面經筆記(十二)

1.以下遞歸函數存在棧溢出的風險,請問如何優化?

function factorial(n){
    return n*factorial(n-1)
}

解答:

function factorial(n){
    if(n === 1) { return 1;};
    return n*factorial(n-1)
}

2.請實現一個計算最大公約數的函數:

function greatestCommonDivisor(a,b){
//在這裏編寫代碼
}
greatestCommonDivisor(8, 12) //4
greatestCommonDivisor(8, 16) //8
greatestCommonDivisor(8, 17) //1

解答:

function greatestCommonDivisor(a,b){
  var num=0;  
      while(b!=0){       
           num=a%b;  
           a=b;  
           b=num;  
      }  
      return a;

}

3.數組去重(如果數組中有NaN)

Array.prototype.uniq = function () {
   var resArr = [];
   var flag = true;
      
   for(var i=0;i<this.length;i++){
       if(resArr.indexOf(this[i]) == -1){
           if(this[i] != this[i]){   

               //排除 NaN
              if(flag){
                   resArr.push(this[i]);
                   flag = false;
              }
           }else{
                resArr.push(this[i]);
           }
       }
   }
    return resArr;
}

4.用 JavaScript 實現斐波那契數列函數,返回第n個斐波那契數。 f(1) = 1, f(2) = 1 等

function fibonacci(n) {
    if(n ==1 || n == 2){
        return 1
    }
    return fibonacci(n - 1) + fibonacci(n - 2);
}

5.根據包名,在指定空間中創建對象

輸入描述:

namespace({a: {test: 1, b: 2}}, 'a.b.c.d')

輸出描述:

{a: {test: 1, b: {c: {d: {}}}}}
function namespace(oNamespace, sPackage) {
 
    var properties = sPackage.split('.');
    var parent = oNamespace;
 
    for (var i = 0, lng = properties.length; i < lng; ++i) {
 
        var property = properties[i];
 
        if (Object.prototype.toString.call(parent[property])!== '[object Object]') {
            parent[property] = {};
        }
 
        parent = parent[property];
 
    }
 
    return oNamespace;
 
}

6.封裝函數 f,使 f 的 this 指向指定的對象

function bindThis(f, oTarget) {
    return function(){
        var parames = Array.prototype.slice.call(arguments);
        return f.apply(oTarget,parames); //注意這裏需要返回f的執行結果
    }  
}

7.dom 節點查找

查找兩個節點的最近的一個共同父節點,可以包括節點自身

輸入描述:

oNode1 和 oNode2 在同一文檔中,且不會爲相同的節點
function commonParentNode(oNode1, oNode2) {
    if(oNode1.contains(oNode2)){
        return oNode1;
    }else if(oNode2.contains(oNode1)){
        return oNode2;
    }else{
        return commonParentNode(oNode1.parentNode,oNode2);
    }
}

8.關係型數組轉換成樹形結構對象

關係型數組:

var obj = [
    { id:3, parent:2 },
    { id:1, parent:null },
    { id:2, parent:1 },
]

期望結果:

o = {
  obj: {
    id: 1,
    parent: null,
    child: {
      id: 2,
      parent: 1,
      child: {
          id: ,3,
          parent: 2
      }
    }
  }
}

實現源碼:

function treeObj(obj) {
  obj.map(item => {
    if (item.parent !== null) {
      obj.map(o => {
        if (item.parent === o.id) {
          if (!o.child) {
            o.child = [];
          }
          o.child.push(item);
          o.child = o.child;
        }
      });
    }
  });
  return obj.filter(item => item.parent === null)[0]
}

或者:

function treeObj(obj) {
  return obj.sort((a, b) => b.parent - a.parent)
      .reduce((acc, cur) => (acc ? { ...cur, child: acc } : cur));
}

9.JS如何判斷一組數字是否連續

// 當出現連續數字的時候以‘-’輸出
[1, 2, 3, 4, 6, 8, 9, 10]

期望結果:

["1-4", 6, "8-10"]

實現代碼:

判斷是否連續:

var arrange = function(arr){
    var result = [],temp = [];
    arr.sort(function(source, dest){
        return source - dest;
    }).concat(Infinity).reduce(function(source, dest){
        temp.push(source);
        if(dest-source > 1){
            result.push(temp);
            temp = [];
        }
        return dest;
    });
    return result;
};

格式化實現:

var formatarr = function(arr) {
    var newArr = []
    var arr1 = arrange(arr)
    for (var i in arr1) {
        var str = '';
        if (arr1[i].length > 1) {
            str = arr1[i][0] + '-' + arr1[i][arr1[i].length - 1];
            newArr.push(str)
        } else {
            newArr.push(arr1[i][0]);
        }
   }
   return newArr;
}

10.創建子類Child,使用原型和構造函數的方式繼承父類People的方法,並調用say函數說出姓名和年齡。

父類:

function People(name,age){
     this.name=name;
     this.age=age;
     this.say=function(){
         console.log("我的名字是:"+this.name+"我今年"+this.age+"歲!");
     };
}

原型繼承:

function Child(name, age){
    this.name = name;
    this.age = age;
}
Child.prototype = new People();
var child = new Child('Rainy', 20);
child.say()

構造函數繼承:

function Child(name, age){
    People.call(this)
    this.name = name;
    this.age = age;
}
var child = new Child('Rainy', 20);
child.say()

組合繼承:

function Child(name, age){
    People.call(this);
    this.name = name;
    this.age = age;
}
Child.prototype = People.prototype;
var child = new Child('Rainy', 20);
child.say()

組合繼承優化:

function Child(name, age){
    People.call(this);
    this.name = name;
    this.age = age;
}
Child.prototype = Object.create(People.prototype);
Child.prototype.constructor = Child;
var child = new Child('Rainy', 20);
child.say()

歡迎關注

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章