前端面試:JS基礎知識梳理

題目一

  1. JS中使用typeof 能獲得哪些類型
  2. 什麼時候使用 === 什麼時候使用==
  3. JS中有哪些內置函數
  4. JS變量按照存儲方式區分爲哪些類型,並描述其特色
  5. 如何理解JSON

JS按照存儲方式分類分爲哪幾種類型:

  • 引用類型:對象、數組、函數
    • 特色:不限制屬性,指針指向共同存儲塊,節省內存空間
  • 值類型: 布爾、num、字符串、underfind
    • 每一個變量單獨一個固定存儲塊

typeof運算符

  • typeof 只能區分值類型數據javascript

    • 引用類型的話只能分辨出函數(function),比較特殊
    typeof undefined  //undefined
    typeof 'abc'      //string
    typeof 123        //number
    typeof true       //boolean
    typeof {}         //object
    typeof []         //object
    typeof null       //object
    typeof console.log //function
    複製代碼

值類型的變量計算:強制類型轉換計算

  • 字符串拼接
  • 雙等好==
  • if語句
  • 邏輯運算符 (&& 、 || 、 !)

什麼時候用 === 什麼時候用 ==

if(obj.a == null){
    //這裏至關於obj.a === null || obj.a=== underfind,簡寫形式
    //這是jq源碼中推薦的寫法
    //除了這個的判斷,其他都建議使用===
}
複製代碼

js中的內置函數有哪些

  • Object
  • Array
  • Boolean
  • Number
  • String
  • Function
  • Date
  • RegExp
  • Error
  • 知道這個的用處就是爲了從此學習構造函數使用

什麼是json

//json 是js中的對象,相似Math,同時也是一種數據格式
// js給他內置了兩個方法
JSON.Stringify({a:1,b:2})  //json轉化爲字符串
JSON.parse('{"a":1,"b":2}') //字符串轉爲json
複製代碼


題目二

  1. 如何判斷一個變量是數組類型
  2. 寫一個原型鏈繼承的例子
  3. 描述new一個對象的過程
  4. zepto(或其餘框架)源碼中如何使用原型鏈

構造函數

function Per(name,age){
    this.name = name;
    this.age = age;
    //return this 默認會返回this,這個this實際上是一個對象
}
var a = new Per('zhangsan',20);
// 構造函數就相似一個模板,把一些相同屬性和方法統一
// 表明着具備相同屬性和方法的類的聚合
// 引用類型的值都具備構造函數,舉例:
var a = {} //實際上是var a = new Object()的語法糖
var a = [] //實際上是var a = new Array()的語法糖
function Foo*(){...} //實際上是 var Foo = new Function(...)
// 構造函數的首字母大寫
複製代碼

原型規則和示例(掌握五個規則)

  • 規則1:全部引用類型(數組、對象、函數),都具備對象特性,便可自由擴展屬性(除了「null」 意外)
  • 規則2:全部引用類型(數組、對象、函數),都有一個 __proto__(隱式原型)屬性,屬性值是一個普通的對象
  • 規則3:全部的函數,都有一個prototype (顯示原型)屬性,屬性值是一個普通對象
  • 規則4: 全部引用類型(數組、對象、函數),__proto__屬性值指向它的構造函數的「prototype」 屬性值
  • 規則5:當試圖獲得一個對象(引用類型)的屬性的時候,若是這個對象沒有這個屬性,那麼會去它的 __proto__(隱式原型)(即它的構造函數的prototype)中尋找
//舉例:對比規則1
var obj = {}; obj.a = 100;
var arr = []; arr.a = 100;
function fn () {}
fn.a = 100;

//舉例:對比規則2
console.log(obj.__proto__);
console.log(arr.__proto__);
console.log(fn.__proto__);

//舉例:對比格則3
console.log(fn.prototype);

//舉例:對比規則4
console.log(obj.__proto__ === Object.prototype) //true

//舉例:對比規則5
//構造函數
function Foo(name, age) {
    this.name = name
}
Foo.prototype.alertName = function () {
    alert(this.name)
}
//建立示例
var f = new Foo('zhangsan')
f.printName = function () {
    console.log(this.name)
}
//測試
f.printName()   //'zhangsan'
f.alertName()   //'zhangsan'
複製代碼

循環對象自身的屬性html

//通常狀況,f函數有三個屬性,name/printName/alertName
//要想拿到對象的本身的屬性
var item;
for (item in f) {
 //高級瀏覽器已經在 for in 中屏蔽了來自原型的屬性
 //可是這裏建議你們加上這個判斷,保證程序的健壯性
 if (f.hasOwnProperty(item)){
     console.log(item)
 }
}
複製代碼

原型鏈(可看圖)

原型鏈

function Foo(name, age) {
    this.name = name
}
Foo.prototype.alertName = function () {
    alert(this.name)
}
//建立示例
var f = new Foo('zhangsan')
f.printName = function () {
    console.log(this.name)
}
//測試
f.printName()   //'zhangsan'
f.alertName()   //'zhangsan'
f.toString() //應該找 f.__proto__.__proto__
//首先找:f有沒有toString 屬性,沒有找 f.__proto__ 即 Foo.prototype
//Foo.prototype是對象,也具備__proto__屬性
//Foo.prototype.__proto__ 是指向Object.prototype
//Object.prototype 有toString()屬性,截止

//在往上的話,js規定,Objcet.prototype.__proto__ 是null,截止
複製代碼

instanceof

  • 是判斷引用類型是屬於哪一個構造函數的方法前端

    var a = [];
    var b = a instanceof Array; 
    //判斷是不是一個數組,引用類型的值用typeof不能判斷
    
    //舉例
    function Foo(name, age) {
        this.name = name
    }
    Foo.prototype.alertName = function () {
        alert(this.name)
    }
    //建立示例
    var f = new Foo('zhangsan')
    var b = f instanceof Foo //判斷f 的構造函數 是否是Foo
    //判斷的邏輯是:f的__proto__一層一層往上,可否對應到Foo的prototype
    
    //再試着判斷 f instanceof Object, 發現可以找到,也是true
    複製代碼

寫一個原型鏈繼承的例子

//動物
function Animal() {
    this.eat = function () {
        console.log('animal eat')
    }
}
//狗
function Dog() {
    this.bark = function () {
        console.log('dog bark')
    }
}
Dog.prototype = new Animal()
//哈士奇
var hashiqi = new Dog()

//則哈士奇繼承了dog的屬性,以及bark的屬性
//以上是小例子便於理解
//下面寫的是貼近實戰的例子
*****


複製代碼

描述new一個對象的過程

function Foo(name, age) {
    this.name = name
    this.age = age
    this.class = 'class-1'
    //retuen this //默認有這個
}
var f = new Foo('zghangsan', 20)

var arr = new Array()
//首先建立一個空對象 this = {}
//this指向這個新的對象
//執行代碼,即對this賦值
//返回this,即返回新建立的對象{}

複製代碼

zepto(或者其餘框架)源碼中如何使用原型鏈

  • 閱讀源碼是高效提升技能的方式
  • 慕課網搜索‘zepto設計和源碼分析’,對於面試來講加分
//仿照相似jQuery,或者zepto 寫一個簡單的原型繼承的例子
function Elem (id) {
    this.elem = document.getElementById(id)
}
Elem.prototype.html = function (val) {
    var elem = this.elem
    if (val) {
        elem.innerHTML = val
        return this //便於鏈式操做
    } else {
        return elem.innerHTML
    }
}

Elem.prototype.on = function (type, fn) {
    var elem = this.elem
    elem.adEventListener(type, fn)
    return this
}

var div1 = new Elem('div1')
//console.log(div1.html())
div1.html('<p>htllo world</p>').on('click', function(){
    alert('clicked')
}).html('<p>javascript</p>')

複製代碼


題目三

  1. 說一下對變量提高的理解
  2. 說明this幾種不一樣的使用場景
  3. 建立10個標籤,點擊的時候彈出來對應的序號
  4. 如何理解做用域
  5. 實際開發中閉包的應用

this

  • this要在執行的時候才能確認值,定義時沒法確認
var a = {
    name: 'A',
    fn: function () {
        console.log(this.name)
    }
}
a.fn  //this === a
a.fn.call({name: 'B'}) //this === {name: 'B'}
var f1 = a.fn
f1() //this === window

複製代碼
  • 幾種this應用場景java

    • 做爲構造函數執行
    • 做爲對象屬性執行
    • 做爲普通函數執行
    function fn() {
       console.log(this)  //這個this === window
    }
    fn()
    
    複製代碼
    • call apply bind面試

      bind得和函數聲明聯合一塊兒用,最經常使用的是callajax

做用域和閉包

  • 一個函數的父級做用域是看這個函數在哪裏定義,不要看在哪裏執行json

  • 閉包的使用場景,一下狀況就是閉包數組

    • 函數做爲返回值瀏覽器

      function F1() {
          var a = 100
          retuen function () {
              console.log(a)  //a是自由變量,父級做用域尋找
          }
      }
      var f1 = F1()
      var a = 200
      f1()   //100
      
      複製代碼
    • 函數做爲參數傳遞網絡

      function F1() {
          var a = 100
          retuen function () {
              console.log(a) 
          }
      }
      var f1 = fn()
      function F2(fn) {
          var a = 200
          fn()
      }
      F2(f1)  //100
      
      複製代碼
  • 實際開發中閉包的應用

    //閉包實際應用中主要是用於封裝變量、收斂權限
    function isFirstLoad() {
        var _list = []
        return function (id) {
            if (_list.indexOf(id) >= 0) {
                return false
            } else {
                _list.push(id)
                retuen true
            }
        }
    }
    //使用
    var firstLoad = isFirstLoad()
    firstLoad(10) //true
    firstLoad(10) //false
    firstLoad(20) //true
    //閉包意義在於:你在isFirstLoad函數外面,根本不可能修改掉_list的值,把一些功能return出去,數據不能更改
    
    複製代碼
  • 解釋自執行函數

    var i
    for (i = 0; i < 10; i++) {
        //每執行一次循環,傳一個i值進去,而後建立一個自執行函數,此時的i就變成函數做用域的值存儲,總共建立10個函數即10個函數做用域
        (function(i){
            //函數做用域
            var a = document.createElement('a')
            a.innerHTML = i + '<br>'
            a.addEventListener('click', function (e) {
                e.preventDefault()
                alert(i) //自由變量,要去父做用域取值
            })
            document.body.appendChild(a)
        })(i)
    }
    
    複製代碼


題目四

  1. 同步和異步區別是什麼?分別舉一個同步和異步的例子
  2. 一個關於setTimeout的筆試題
  3. 前端使用異步的場景有哪些

異步

  • 何時使用異步(須要等待的任務)
    1. 定時任務:setTimeout, setInterval
    2. 網絡請求:ajax請求,動態加載
    3. 事件綁定

數組API

  • forEach 遍歷全部元素

  • every 判斷全部元素是否都符合條件

  • some 判斷是否有至少一個元素符合條件

  • sort 數組排序

  • map 對元素從新組裝,生成新數組

  • filter 過濾符合條件的元素

    // forEach
    var arr = [1,2,3]
    arr.forEach(function (item, index) {
        //遍歷全部元素
        console.log(index, item)
    })
    
    //every
    var arr = [1,2,3]
    var result = arr.every(function (item, index) {
        //判斷全部數組元素,都知足一個條件
        if (item < 4) {
            return true
        }
    })
    console.log(result)
    
    //sort
    var arr = [1,4,3,2,5]
    var arr2 = arr.sort(function (a, b) {
        //從小到大排序
        return a - b
        
        //從大到小排序
        //return b - a
    })
    console.log(arr2)
    
    // map
    var arr = [1,2,3,4]
    var arr2 = arr.map(function (item, index) {
        //將元素從新組裝返回
        return '<b>' + item + '</b>'
    })
    console.log(arr2)
    
    //filter
    var arr = [1,2,3]
    var arr2 = arr.filter(function (item, index) {
        //經過一個條件過濾數組
        if (item >= 2) {
            return true
        }
    })
    console.log(arr2)
    
    複製代碼

對象API

  • for in

    var obj = {
        x: 100,
        y: 200,
        z: 300
    }
    var key
    for (key in obj) {
        //hasOwnProperty表示自有的屬性
        if (obj.hasOwnProperty(key)) {
            console.log(key, obj[key])
        }
    }
    
    複製代碼

寫一個既能遍歷對象也能遍歷數組的forEach函數

相關文章
相關標籤/搜索