web前端面試套路(完整的體系) 層層深刻

1、變量、JS部分

一.JS的數據類型

  • 基本數據類型 (number, string, boolean, null[空指針], undefined) 存儲的是值
  • 引用數據類型(object[[]], {},new Boolean()], function) 存儲的是引用地址(指向同一個內存地址,一個變,另外一個會隨之改變)
  • es6 symobl [Symbol函數前不能使用new命令,不然會報錯。這是由於生成的Symbol是一個原始類型的值,不是對象]
注意: 基本數據類型用new關鍵字也會變成一個一個應用數據類型,是一個實例了
如何判斷一個值是不是null
function checkNull(val) {
      return  typeof val === 'object' && val === val;
 }
 checkNull()
複製代碼
如何判斷一個值是不是NaN
function checkNaN(val) {
      return  val.toSring() === 'NaN';
 }
 checkNull() 
複製代碼

二.如何檢測數據類型

  • typeof typeof() 是一個一元運算符,能夠不加括號,是等價的, 返回一個類型字符串 用法==>> typeof typeof()vue

    • 只能檢測基本數據類型,不能區分引用數據類型,引用數據類型都返回'object'
    • 如何區分null和object類型
    • 如何區分function 和 symbol類型
    有六種結果==>: 'number', 'string', 'boolean', 'object'[null], 'function'[Symobl], 'undefined'
        typeof null = > 'object'
        typeof Symobl('es6') => 'function'
        typeof typeof typeof typeof [] => 'string'
    複製代碼
  • instanceof 只要在原型鏈上便可, 用法==>> 值 instanceof 類react

    • Object類是全部類的基類
    • Function類是全部函數的基類
[] instanceof Array // true
  [] instanceof Object  // true
  null instanceof Object //false    null空對象使用
複製代碼
  • constructor 利用函數原型上的constructor執行類自己去判斷(原型鏈機制去查找)
  • 在原型繼承的時候會打斷了,須要手動設置construct的值 [子類的.prototyep.constrcutor = 子類]
機制是:實例.__proto ===類的.prototype.constructr
     function fn() {}
     [].constrcutor === Array;  / false
     fn.constrcutor === Object  // false
     fn.constructor === Function //true
     
     function A() {}
     A.prototype.getX() {};
     
     function B() {}
     B.protype = new A();
     B.prototype.constructor = B; //====>>手動設置constructor的值,設置會執行父類A
複製代碼
  • Object.prototype.toString.call(val) 返回'[object 類的自己]' 改變this,返回類自己,最好的
1.封裝檢測數據類型和判斷數據類型各個方法
     const tool = function(window, undefined) {
          let box = {
              checkTypeof(val) {
                  return Object.prototype.toString.call(val);  
              },
              isNumber(val) {
                  return Object.prototype.toString.call(val) === '[object Number]';
              },
              isString(val) {
                  return Object.prototype.toString.call(val) === '[object String]';
              },
              isBoolean(val) {
                  return Object.prototype.toString.call(val) === '[object Boolean]';
              },
              isNull(val) {
                  return Object.prototype.toString.call(val) === '[object Null]';
              },
              isUndefined(val) {
                  return Object.prototype.toString.call(val) === '[object Undefined]';
              },
              isFunction(val) {
                  return Object.prototype.toString.call(val) === '[object Function]';
              },
              isObject(val) {
                  return Object.prototype.toString.call(val) === '[object Object]';
              },
              isArray(val) {
                  return Object.prototype.toString.call(val) === '[object Array]';
              },
              isSymbol(val) {
                  return Object.prototype.toString.call(val) === '[object Symbol]';
              },
              isExpRep(val) {
                  return Object.prototype.toString.call(val) === '[object ExpRep]';
              },
          };
          return box;
    }();

2. 如何判斷一個變量是不是數組
     - instanceof     val instanceof Array
     - constrcutor    val.constrcutor === Array
     - Array.isArray(val)
     - Object.prototype.toString.call(val)   ==> '[object Array]'   => 最靠譜,最安全
     
     注意:constrcutor和isArray在兩個iframe,在哪一個iframe中間判斷,由於是倆個window對象,會有問題
複製代碼

3、數組方法

  • es3
push => pop  
unshift => shift
splice(n, m, val) 截取  從n,刪除m個元素,用val去替換
slice(n,[m])    篩選,從索引n,查找到索引m,不包含m
conact  合併數組
reverse  倒敘     判斷迴文數面試題
sort((a,b) => a-b);  排序, 原理是冒泡排序  手寫冒泡排序
indexOf([n]) => lastIndexOf([n]) 原理是,遍歷進行===進行比較,因此NaN是找不到的 NaN === NaN =>false   查找這個東西,返回索引值,沒有返回-1,前,後查找  
join 手拉手 轉爲字符串 split劈開轉爲數組

複製代碼
  • es5 都是callback進行處理,不會改變原來數組, 本身封裝
forEach  遍歷
filter   過濾,篩選出符合條件的數據
map      映射, 一組數據對應
reduce   計算
some     所有是否符合
every    任意一個符合


myForEach:
   Array.prototype.myForEach = function (callback) {
       if (typeof callback == 'function') {
           for (let i = 0; i < this.length; i++) {
               callback.call(this, this[i], i, this);
           }
       }
   };

myMap:
   Array.prototype.myMap = function (callback) {
       let ary = [];
       if (typeof callback == 'function') {
           for (let i = 0; i < this.length; i++) {
               ary.push(callback.call(this, this[i], i, this));
           }
       }
       return ary;
   };


myFilter:
   Array.prototype.myFilter = function (callback) {
       let ary = [];
       if (typeof callback == 'function') {
           for (let i = 0; i < this.length; i++) {
             if (callback.call(this, this[i], i, this)) {
                 ary.push(this[i]);
             }
           }
       }
       return ary;
   };

複製代碼
  • es6
find => findIndex 數組實例的find方法,用於找出第一個符合條件的數組成員
fill(val) 快速填充數組,
includes =>原理Ojbect.is(),因此他能夠處理數組裏面的NaN值,查找某個元素在數組裏面,找到返回true,反之false

複製代碼
*** 1.哪些方法是改變原來的數組
push pop shift unshift  splice sort reverse

其餘返回原數組,或者布爾值,索引
複製代碼
*** 2.手寫冒泡排序
Array.prototype.mySort = function() {
    for(let i=0;i<this.length-1;i++) {
        for(let k=0;k=this.length-1-i;k++) {
            if(this[k] > this[k+1]) {
                let templ = this[k];
                this[k] = this[k+1];
                this[k+1] = this[k];
            }
        }
    }
    return this;
};
複製代碼
*** 3.在數組裏面查找NaN
  • indexOf, lastIndexOf, 循環遍歷,嚴格比較(===) 處理不了NaN
  • includes =>Object.is()原理 處理NaN的
*** 4.如何快速建立10000個值都是爲1的數組
let ary = new Array(1000).fill(1);
 console.log(ary);
複製代碼

4、數組去重

*** 因爲考慮NaN問題,比較會返回false問題,咱們一概採用Object.is()方法,查找一概採用includes方法
  • 建立空數組,循環判斷進行push, 注意,考慮到NaN最好用includes, 建議不用indexOf過濾不掉的,NaN ===NaN false
Array.prototype.myUnique = function () {
            let ary = [];
            for (let i = 0; i < this.length; i++) {
                console.log(ary.includes(this[i]))
                if (!ary.includes(this[i])) {
                    ary.push(this[i]);
                }
            }
            return ary;
    }
    let s= ([1, 2, 2, 1, 3, 4, 1, 2, 3,NaN, null,NaN].myUnique())
複製代碼
  • 原數組進行排序,相鄰進行對比,重複,splice刪除,i--
Array.prototype.myUnique = function () {
           this.sort((a, b) => a-b);

           for(let i=0;i<this.length;i++) {
               if (this[i] === this[i+1]) {    ==>>Object.is(this[i], this[i+1])
                   this.splice(i ,1);
                   i--;
                   continue;
               }
           }
           return this;
        }
        var s= [1, 2, 2, 1, 3, 4, 1, 2, 3,NaN, null,NaN].myUnique();
        
        [null, 1, 2, 3, 4, NaN, NaN]; 去不掉NaN, 由於NaN === NaN;是不相等的,NaN除了數字其餘東西,鬼知道呢
        
    ====>> 優化去掉NaN;
         this[i] === this[i+1]不能夠排除,咱們用Object.is(this[i], this[i+1])不就能夠了嘛
複製代碼
  • 對象去重複(對象的屬性不能重複)
Array.prototype.myUnique = function () {
        let obj = {};
        for (let i = 0; i < this.length; i++) {
            let cur = this[i];
            if (obj[cur] === cur) {  // ===>> Object.is(obj[cur] === cur)
                this.splice(i, 1);
                i--;
                continue;
            }
            obj[cur] = cur;
        }
        obj = null;  // ===>>釋放內存,優化
        return this;  // ===>> 鏈式調用
    }
    var s = [1, 2, 2, 1, 3, 4, 1, 2, 3, NaN, null, NaN].myUnique();
    s => [1, 2, 3, 4, NaN, null, NaN]
    也是嚴格對NaN問題,Object.is(obj[cur] === cur)
複製代碼
  • es6 [ ...new Set(val) ] set數據解構配合數組拓展符運算符
Array.prototype.myUnique = function () {
        return [... new Set(this)]
    }
    var s = [1, 2, 2, 1, 3, 4, 1, 2, 3, NaN, null, NaN].myUnique();
    s ==> [1, 2, 3, 4, NaN, null]
複製代碼

4、僞數組轉爲數組

1.僞數組:
  • DOM選擇器選擇出來的列表
  • 函數的arguments對象
  • jQ裏面的選擇出來的對象是
2.轉換爲數組
第一種方法,封裝方法,遍歷push
function toArray(likeAry) {
    if (likeAry && likeAry.length) {
        let ary = [];
        for (let i = 0; i < this.length; i++) {
            ary.push(this[i]);
        }
        return ary;
    }

    return [];
}
console.log(toArray(document.getElementsByTagName('*')) instanceof Array) // true
複製代碼
第二種方法,藉助數組原型上的方法slice,截取,改變this執行,上面是slice的封裝
  • Array.prototype.slice.call(likeAry);
  • [].slice(likeAry); ==> [].proto..slice
function fn() {
     arguments = Array.prototype.slice(arguments);
     arguments = Array.from(arguments);
 }
複製代碼
第三種方法,es6 Array.from(likeAry);
function toArray(likeAry) {
      return Array.from(likeAry);
  }
  
複製代碼

5、遍歷數組方法總結 (面試題)

=>說說for、 for-in、 forEach 、for -of 區別
  • for循環
    • 不會遍歷出私有的屬性
    • 編程式,知道原理
  • forEach循環
    • 不能return
    • 不能遍歷出私有屬性
    • 聲明式編程, 不知道原理,用便可, vue就是
  • for - in 循環
    • 能夠遍歷出私有的屬性,利用hasOwnproperty()進行過濾
  • for - of循環 ES6完美解決上面問你
    • 能夠return
    • 不會遍歷出私有的屬性
    • 只能遍歷數組
  • myForEach封裝,就是回調函數(在原型上擴展)
Array.prototype.myForEach = function(callback) {
  if (typeof callback == 'function') {
      for (let i =0;i<this.length;i++) {
          callback.call(this,this[i], i, this);
      }
  }
};

  var ary  = ['vue', 'react', 'angular'];
  ary.myForEach(function(item, index, slef) {
      console.log(item, index, slef)
  });
複製代碼
1.for循環 // ==>> 不會遍歷出私有的屬性
     let ary = [1, 2, 3];
     ary.b = 100;
     for (let i=0,len=ary.length;i<len;i++) {
          console.log(ary);   
     }
     
  2. forEach // ==>> 不能return,不會遍歷出私有的屬性
     ary.forEach((item, index, self)=> {
      console.log(item);   
     });
     
  3.for - in   // ==>> key會變成字符串,而且會遍歷出私有的屬性,利用hasOwnproperty進行過濾
    for(let key in ary) { 
       if (!ary.hasOwnproperty(key)) {
            conosle.log(key)
       }
    }
    
  4.for - of  // ==>> 能夠return, 可是必須是數組,不能遍歷對象
   for(let key of ary) {  
       
   }
   實現想遍歷對象:  Object.keys(); //====>>將一個對象的屬性依次放到一個數組中,返回一個新的數組
      let obj = {school:'科師',age:9};
      for (let key of Ojbect.keys(obj) {
          console.log(obj[key]);
      }
複製代碼

4、字符串方法

  • es3
chartAt(index) 返回子字符串,index爲字符串下標,index取值範圍[0,str.length-1]
chatCodeAt(index) 返回子字符串的unicode編碼,index取值範圍同上

查找方法: 
indexOf(searchString,startIndex)返回子字符串第一次出現的位置,從startIndex開始查找,找不到時返回-1
lastIndexOf(searchString,startIndex) 從由往左找子字符串,找不到時返回-1

截取方法 
substr(start,end) 兩個參數都爲正數,返回值:[start,end) 也就是說返回從start到end-1的字符
substring(start,end)  返回從 start 到 end(不包括)之間的字符,start、end均爲 非負整數。若結束參數(end)省略,則表示從start位置一直截取到最後。
slice 兩個參數可正可負,負值表明從右截取,返回值:[start,end)也就是說返回從start到end-1的字符

字符串分割成數組
str.split(separator,limit);  參數1指定字符串或正則,參照2指定數組的最大長度
  - str.split("");  每一個字符都被分割  ['','','','']
  - str.split();    整個字符串放到數組裏  ['']
  
str.replace(rgExp/substr,replaceText)   返回替換後的字符串

英文轉換
toLowerCase() 轉小寫
toUpperCase() 轉大寫
複製代碼

後續天天更新es6

1、CSS部分

相關文章
相關標籤/搜索