從面試題看考察知識(shí)點(diǎn)(二)

題目三

  • 說(shuō)一下對(duì)變量提升的理解
    • 變量定義(提升)
    • 函數(shù)聲明(提升)
  • 說(shuō)明 this 幾種不同的使用場(chǎng)景
  • 創(chuàng)建 10 個(gè) <a> 標(biāo)簽, 點(diǎn)擊的時(shí)候彈出不同的序號(hào)
    for(var i = 0; i < 10; i++) {
      (function(i){
        var a = document.createElement('a')
        a.innerHTML =i + '<br>'
        a.addEventListener('click', function(e){
          console.log(i)
        })
        document.body.appendChild(a)
      })(i)
    }
    
  • 如何理解作用域
    • 自由變量
    • 作用域鏈,查找自由變量
    • 閉包的兩個(gè)場(chǎng)景
  • 實(shí)際開發(fā)中閉包的應(yīng)用
    // 封裝變量, 收斂權(quán)限
    function isFirstLoad() {
      var _list = []
      return function (id) {
        if (_list.indexOf(id) >=0 ) {
          return false
        } else {
          _list.push(id)
          return true
        }
      }
    }
    
    var firstLoad = isFirstLoad()
    console.log(firstLoad(10))  // true
    console.log(firstLoad(10))  // false
    console.log(firstLoad(20))  // true
    

知識(shí)點(diǎn)

  1. 執(zhí)行上下文
  • 范圍: 一段<script> 或者一個(gè)函數(shù)
  • 全局: 變量定義, 函數(shù)聲明, 一段<script>
  • 函數(shù): 變量定義, 函數(shù)聲明, this arguments 函數(shù)
<script>
    console.log(a)  // undefined 變量提升
    var a = 100
    
    fn('yym')  // 'yym' 20
    function fn(name) {  // 函數(shù)聲明 提升
        age = 20
        console.log(name,age)
        var age
    }
</script>
  1. this
  • this 要在執(zhí)行時(shí)才能確認(rèn)值, 定義時(shí)無(wú)法確認(rèn)
    • 作為構(gòu)造函數(shù)執(zhí)行
    • 作為對(duì)象屬性執(zhí)行
    • 作為普通函數(shù)執(zhí)行
    • call apply bind
var a = {
  name: 'yym',
  fn: function () {
    console.log(this.name)
  }
}
// 不看下面, 上面不能確定this指啥

a.fn()  // this === a
a.fn.call({name: 'B'})  // this === {name: B}
var fn1 = a.fn
fn1()  // this === window

代碼演示

function Foo(name) {
    // this = {}
    this.name = name
    // return this
}
var f = new Foo('yym')  // 構(gòu)造函數(shù)的 this

var obj = {
    name: 'A',
    printName: function () {
        console.log(this.name)
    }
}
obj.printName()  // 作為對(duì)象屬性執(zhí)行 this === Obj

function fn () {
    console.log(this)
}
fn()  // 作為普通函數(shù)執(zhí)行 this === window

function fn1 (name) {
    console.log(this)
}
fn1.call({x: 100}, 'yym') // call this === {x: 100} apply 第二個(gè)參數(shù)是數(shù)組

var fn2 = function (name) {
    console.log(this)
}.bind({y: 150})  // .bind 是一個(gè)函數(shù)表達(dá)式
fn2('yym') // this === {y:150}
  1. 作用域
  • JS沒有塊級(jí)作用域
  • 只有函數(shù)和全局作用域
// 無(wú)塊級(jí)作用域
if (true) {
    var name = 'yym'
}
console.log(name)  // 可以訪問到 var name = 'yym'

// 函數(shù)和全局作用域
var a = 100
function fn() {
    var a = 200
    console.log('fn', a)  // fn 200
}
console.log('global', a)  // global 100
fn()
  1. 作用域鏈
var a = 100
function fn () {
    var b = 200
    
    // 當(dāng)前作用域沒有定義的變量, 即'自由變量'
    console.log(a)  // 在當(dāng)前作用域找不到變量 a, 去父級(jí)作用域去找
    console.log(b)
}
var a = 100
function F1 () {
    var b = 200
    function F2() {
        // 當(dāng)前作用域沒有定義的變量, 即'自由變量'
        console.log(a)
        console.log(b)        
        console.log(c)
    }
    F2()
}
F1()

有 3個(gè)作用域: F2作用域, F1作用域, 全局作用域

a 在 F2 中沒有, 去F1 作用域找, 沒有, 繼續(xù)去全局作用域找
b 在 F2 中沒有, 在F1 作用域找到了 
  1. 閉包
function F1() {
    var a = 100
    
    // 返回一個(gè)函數(shù), (函數(shù)作為返回值)
    return function () {
        console.log(a)  // 自由變量, 到父級(jí)作用域去找
    }
}
var f1 = F1()
var a = 200
f1()  // 100
  1. 閉包的使用場(chǎng)景
  • 函數(shù)作為返回值
  • 函數(shù)作為參數(shù)傳遞
// 函數(shù)作為參數(shù)傳遞
function F1() {
    var a = 100
    return function () {
        console.log(a)  // 自由變量, 到父級(jí)作用域去找
    }
}
var f1 = F1()

function F2(fn) {
    var a = 200
    fn()
}
F2(f1)  // 把f1 作為參數(shù)傳進(jìn)去 100

題目四

  • 同步和異步的區(qū)別是什么? 分別舉一個(gè)同步和異步的例子
    • 同步會(huì)阻塞代碼執(zhí)行, 而異步不會(huì)
    • alert是同步, setTimeout是異步
  • 一個(gè)關(guān)于setTimeout的筆試題
    console.log(1)
    setTimeout(() => {
        console.log(2)
    }, 0)
    console.log(3)
    setTimeout(() => {
        console.log(4)
    }, 1000)
    console.log(5)  // 1 3 5 2 1s后打印 4
    
  • 前端使用異步的場(chǎng)景有哪些
    • ajax 動(dòng)態(tài)<img>加載
    • setTImeout setInterval
    • 事件綁定

知識(shí)點(diǎn)

  1. 什么是異步 (對(duì)比同步)
console.log(100)
setTimeout(() => {
    console.log(200)
}, 1000)
console.log(300)

如果是同步: 先打印100, 停頓1s后打印200, 然后打印300, 這肯定不是我們希望的,我們不希望它停頓
異步: 打印100, 打印300, 1s后打印200,不阻礙后面程序的加載

console.log(100)
alert(200)  // 你什么時(shí)候點(diǎn)掉,什么時(shí)候執(zhí)行后面的,會(huì)卡在那兒
console.log(300)
  1. 前端使用異步的場(chǎng)景
  • 在可能發(fā)生等待的情況

  • 等待過程中不能像alert一樣阻塞程序進(jìn)行

  • "等待的情況" 都需要異步

    • 定時(shí)任務(wù): setTimeout setInterval
    • 網(wǎng)絡(luò)請(qǐng)求: ajax請(qǐng)求, 動(dòng)態(tài)<img>加載
    • 事件綁定
    // ajax請(qǐng)求, 異步
    console.log('start')  // 1.start
    $.get('url',function(data1) {  // 異步 3.data1
        console.log('data1')
    })
    console.log('end')  // 2.end
    
    // 事件綁定 異步
    console.log('start')  // 1.start
    $('#app').addEventListener('click', function () {
        alert('clicked')
    })
    console.log('end')  // 2.end
    
  1. 異步和單線程
  • JavaScript是單線程語(yǔ)言,因此,在一個(gè)進(jìn)程上,只能運(yùn)行一個(gè)線程,而不能多個(gè)線程同時(shí)運(yùn)行。也就是說(shuō)JavaScript不允許多個(gè)線程共享內(nèi)存空間。因此,如果有多個(gè)線程想同時(shí)運(yùn)行,則需采取排隊(duì)的方式,即只有當(dāng)前一個(gè)線程執(zhí)行完畢,后一個(gè)線程才開始執(zhí)行。
  • 任務(wù)隊(duì)列
    • 單線程就意味著,所有任務(wù)(線程)需要排隊(duì),前一個(gè)任務(wù)結(jié)束,才會(huì)執(zhí)行后一個(gè)任務(wù)。如果前一個(gè)任務(wù)耗時(shí)很長(zhǎng),后一個(gè)任務(wù)不得不一直等待。
    • 同步任務(wù)指的是,在主線程上排隊(duì)執(zhí)行的任務(wù),只有前一個(gè)任務(wù)執(zhí)行完畢,后一個(gè)任務(wù)才會(huì)執(zhí)行;異步任務(wù)指的是不進(jìn)入主線程、而進(jìn)入任務(wù)隊(duì)列的任務(wù),只有當(dāng)主線程上的所有同步任務(wù)執(zhí)行完畢之后,主線程才會(huì)讀取任務(wù)隊(duì)列,開始執(zhí)行異步任務(wù)。
console.log(100)
setTimeout(() => {
    console.log(200)
})
console.log(300)

執(zhí)行過程: 先打印100 , 遇到setTImeout異步會(huì)把里面的東西放到任務(wù)隊(duì)列, 在打印 300,打印完成, 然后執(zhí)行任務(wù)隊(duì)列的工作

函數(shù) setTimeout 接受兩個(gè)參數(shù):待加入隊(duì)列的消息和一個(gè)延遲(可選,默認(rèn)為0)。這個(gè)延遲代表了消息被實(shí)際加入到隊(duì)列的最
小延遲時(shí)間。如果隊(duì)列中沒有其它消息,在這段延遲時(shí)間過去之后,消息會(huì)被馬上處理。但是,如果有其它消息,
setTimeout 消息必須等待其它消息處理完。因此第二個(gè)參數(shù)僅僅表示最少延遲時(shí)間,而非確切的等待時(shí)間。

題目五

  • 獲取2019-02-10格式的日期
    function formatDate(dt) {
      if (!dt) {
        dt = new Date()
      }
      var year = dt.getFullYear()
      var month = dt.getMonth() + 1
      var date = dt.getDate()
      if (month < 10) {
        // 強(qiáng)制類型轉(zhuǎn)換
        month = '0' + month
      }
      if (date < 10) {
        // 強(qiáng)制類型轉(zhuǎn)換
        date = '0' + date
      }
      // 強(qiáng)制類型轉(zhuǎn)換
      return year + '-' + month + '-' + date
    }
    console.log(formatDate())
    
  • 獲取隨機(jī)數(shù),要求長(zhǎng)度一致的字符串格式
    var random =Math.random();
    random = random+'0000000000'
    random = random.slice(0,10)
    console.log(random)
    
  • 寫一個(gè)能遍歷對(duì)象和數(shù)組的通用 forEach 函數(shù)
    function forEach(obj,fn) {
      var key
      if (obj instanceof Array) {
        //判斷是不是數(shù)組
        obj.forEach(function (item, index) {
          fn(index, item)
        })
      } else {
        // 不是數(shù)組就是對(duì)象
        for (key in obj) {
          fn(key, obj[key])
        }
      }
    }
    
    var arr = [1, 2, 3]
    forEach(arr, function (index, item) {
      console.log(index, item)
    })
    
    var obj = {x: 100, y: 200}
    forEach(obj, function(key, value) {
      console.log(key, value)
    })
    

知識(shí)點(diǎn)

  1. 日期
Date.now()  // 獲取當(dāng)前時(shí)間的毫秒數(shù) 1549788153194

var dt = new Date()
dt.getTime()  // 獲取毫秒數(shù)
dt.getFullYear()  // 得到年
dt.getMonth()  // 獲取的是 0-11, 所以要 + 1
dt.getDate()  // 獲取日 0-31
dt.getHours()  // 獲取小時(shí) 0-23
dt.getMinutes()  // 獲取分鐘 0-59
dt.getSeconds()  // 獲取秒 0-59
  1. Math
  • 獲取隨機(jī)數(shù) Math.random()
  1. 數(shù)組 API
  • forEach 遍歷所有元素
  • every 判斷所有元素是否都符合條件
  • some 判斷是否至少一個(gè)元素符合條件
  • sort 排序
  • map 對(duì)元素重新組裝,生成新數(shù)組
  • filter 過濾符合條件的元素
var arr = [1,2,3]

arr.forEach(function (item,index) {
    // 遍歷數(shù)組所有元素
    console.log(index,item)
})

var result = arr.every(function (item, index) {
  // 用來(lái)判斷所有的數(shù)組元素,都滿足一個(gè)條件
  if( item < 4) {
    return true
  }
})
console.log(result)  // true

var result = arr.some(function (item, index) {
  // 用來(lái)判斷所有的數(shù)組元素, 只要有一個(gè)滿足條件即可
  if( item < 2) {
    return true
  }
})
console.log(result)  // true

var arr = [1,4,3,5,2]
var arr2 = arr.sort(function (a, b) {
  // 從小到大排序
  return a - b
})
console.log(arr2)

var arr = [1,2,3,4]
var arr2 = arr.map(function(item,index) {
  // 將元素重新組裝, 并返回
  return item * 2
})
console.log(arr2)

var arr = [1,2,3]
var arr2 = arr.filter(function(item,index) {
  // 通過某一條件過濾
  if (item >= 2) {
    return true
  }
})
console.log(arr2)  // [2, 3]
  1. 對(duì)象API
  • for in
var obj = {
  x: 100,
  y: 200,
  z: 300
}
var key
for (key in obj) {
  if (obj.hasOwnProperty(key)) {
    console.log(key, obj[key])
  }
}

從面試題看考察知識(shí)點(diǎn)(一)
從面試題看考察知識(shí)點(diǎn)(三)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 轉(zhuǎn)載請(qǐng)著名出處 GitHub-TYRMars 文章Github地址 JavaScript基礎(chǔ)知識(shí)剖析 01 01-...
    TYRMars閱讀 632評(píng)論 0 7
  • 工廠模式類似于現(xiàn)實(shí)生活中的工廠可以產(chǎn)生大量相似的商品,去做同樣的事情,實(shí)現(xiàn)同樣的效果;這時(shí)候需要使用工廠模式。簡(jiǎn)單...
    舟漁行舟閱讀 8,120評(píng)論 2 17
  • 第一部分 HTML&CSS整理答案 1. 什么是HTML5? 答:HTML5是最新的HTML標(biāo)準(zhǔn)。 注意:講述HT...
    kismetajun閱讀 28,804評(píng)論 1 45
  • 單例模式 適用場(chǎng)景:可能會(huì)在場(chǎng)景中使用到對(duì)象,但只有一個(gè)實(shí)例,加載時(shí)并不主動(dòng)創(chuàng)建,需要時(shí)才創(chuàng)建 最常見的單例模式,...
    Obeing閱讀 2,314評(píng)論 1 10
  • “一位商人派他的兒子去向人類的智慧大師討教幸福的秘密。少年在沙漠中跋涉了四十天,最后來(lái)到一座美麗的城堡。城堡坐落在...
    把躁郁當(dāng)做朋友007閱讀 546評(píng)論 2 0

友情鏈接更多精彩內(nèi)容