前言
題目來自Daily-Interview-Question 木易楊
歡迎star,加入討論
本文記錄自己對題目的解決方式以及綜合大神們的看法吏口。
題目
1拯田、請寫出如下代碼的打印結(jié)果
var name = 'Tom';
(function() {
if (typeof name == 'undefined') {
var name = 'Jack';
console.log('Goodbye ' + name);
} else {
console.log('Hello ' + name);
}
})();
答案:
Goodbye Jack
題目變形:
ldlcoder給出了題目變形,將var name = 'Jack'
變成了let name = 'Jack'
var name = 'Tom';
(function() {
if (typeof name == 'undefined') {
let name = 'Jack';
console.log('Goodbye ' + name);
} else {
console.log('Hello ' + name);
}
})();
答案:
Hello Tom
理由:
我自己的理解:
var 聲明的變量沒有塊作用域荔棉,也就是說會有變量提升酝锅,提升到function作用域的最上層诡必,只是聲明了變量,但是沒有賦值屈张,所以是undefined擒权。
let存在暫時性死區(qū),不會有變量提升阁谆,也就是說function一開始是找不到name這個變量的,然后他會去外層找name愉老,一直找到window下name這個變量场绿,得到typeof name === 'string'
,打印Hello Tom
2嫉入、什么是防抖和節(jié)流焰盗?有什么區(qū)別?如何實現(xiàn)咒林?
答案:
防抖
我覺得這篇文章講的不錯
JavaScript專題之跟著underscore學(xué)防抖
節(jié)流
JavaScript專題之跟著 underscore 學(xué)節(jié)流
例如說:
有一個按鈕點擊會觸發(fā)網(wǎng)絡(luò)請求熬拒,但是我們并不希望每次點擊都發(fā)起網(wǎng)絡(luò)請求,而是當(dāng)用戶點擊按鈕一段時間后沒有再次點擊的情況才去發(fā)起網(wǎng)絡(luò)請求垫竞,對于這種情況我們就可以使用防抖澎粟。
滾動事件中需要做個復(fù)雜計算蛀序。
鼠標(biāo)移動時頻繁觸發(fā)事件的時候。
...
防抖
在這篇文章里 JavaScript專題之跟著underscore學(xué)防抖
給出的防抖函數(shù)
最初版:
function debounce(func, wait) {
var timeout
return function () {
//清除計時器
clearTimeout(timeout)
//延遲一段時間執(zhí)行
timeout = setTimeout(func, wait)
}
}
function getUserAction() {
container.innerHTML = count++
}
//鼠標(biāo)滑過的過程中不觸發(fā)活烙,執(zhí)行完最后一次滑動事件時徐裸,一秒鐘之后執(zhí)行一次
container.mousemove = debouce(getUserAction, 1000)
修正this指向
這里apply返回的是調(diào)用有指定this值和參數(shù)的函數(shù)的結(jié)果。
Function.prototype.apply() MDN
所以要用function包起來
function debounce(func,wait) {
var timeout
return function(){
var context = this
//清除計時器
clearTimeout(timeout)
//延遲一段時間執(zhí)行
timeout = setTimeout(function(){
func.apply(context)
}, wait)
}
}
傳入event對象
function debounce(func,wait) {
var timeout
return function(){
var context = this
var args = arguments
//清除計時器
clearTimeout(timeout)
//延遲一段時間執(zhí)行
timeout = setTimeout(function(){
func.apply(context, args)
}, wait)
}
}
加入立即執(zhí)行的效果
function debounce(func, wait, immediate) {
var timeout
return function () {
var context = this
var args = arguments
if (timeout) clearTimeout(timeout)
if (immediate) {
/*timeout這個變量一開始是undefined,所以callNow為true
這個時候開始到if(callNow)這條語句啸盏,調(diào)用了func.apply重贺,使innerHTML+1
等待wait毫秒之后,返回timeout為null回懦,又觸發(fā)func.apply達到立即執(zhí)行的目的
*/
var callNow = !timeout
timeout = setTimeout(function(){
timeout = null
}, wait)
if (callNow) func.apply(context, args)
}
else {
timeout = setTimeout(function(){
func.apply(context, args)
}, wait)
}
}
}
節(jié)流
JavaScript專題之跟著 underscore 學(xué)節(jié)流
防抖和節(jié)流不一樣气笙,防抖動是將多次執(zhí)行變?yōu)樽詈笠淮螆?zhí)行,節(jié)流是將多次執(zhí)行變成每隔一段時間執(zhí)行怯晕。
關(guān)于節(jié)流的實現(xiàn)健民,有兩種主流的實現(xiàn)方式,一種是使用時間戳贫贝,一種是設(shè)置定時器秉犹。
先寫一版時間戳的方法
其中+new Date()
相當(dāng)于ToNumber(new Date())
// 第一版
function throttle(func, wait) {
var context, args;
var previous = 0;
return function() {
var now = +new Date();
context = this;
args = arguments;
if (now - previous > wait) {
func.apply(context, args);
previous = now;
}
}
}
var count = 1;
var container = document.getElementById('container');
function getUserAction() {
container.innerHTML = count++;
};
container.onmousemove = throttle(getUserAction, 1000);
未完待續(xù)