前端強化 (六月)

1.閉包

閉包是指有權訪問另一個函數做用域中的變量的函數,主要是下面兩點:面試

  • 是一個函數
  • 能訪問另一個函數做用域中的變量

函數柯里化

// 木易楊
const add = (...args) => args.reduce((a, b) => a + b);

// 簡化寫法
function currying(func) {
    const args = [];
    return function result(...rest) {
        if (rest.length === 0) {
          return func(...args);
        } else {
          args.push(...rest);
        	return result;
        }
    }
}

const sum = currying(add);

sum(1,2)(3); // 未真正求值
sum(4); 		 // 未真正求值
sum(); 			 // 輸出 10
複製代碼

2. EventLoop

<!--1-->
setImmediate(() => {
  console.log('setImmediate1')
  setImmediate(() => {
    console.log('setImmediate2')
  })
  process.nextTick(() => {
    console.log('nextTick')
  })
})

setImmediate(() => {
  console.log('setImmediate3')
})
輸出:
setImmediate1
setImmediate3
nextTick
setImmediate2
<!--2-->
setImmediate(() => {
  console.log(1)
  setTimeout(() => {
    console.log(2)
  }, 100)
  setImmediate(() => {
    console.log(3)
  })
  process.nextTick(() => {
    console.log(4)
  })
})
process.nextTick(() => {
  console.log(5)
  setTimeout(() => {
    console.log(6)
  }, 100)
  setImmediate(() => {
    console.log(7)
  })
  process.nextTick(() => {
    console.log(8)
  })
})
console.log(9)
輸出:
9
5
8
1
7
4
3
6
2
複製代碼

3. 經典js new 面試題(注意後三個運算優先級)

new (帶參數列表)優先級大於new (無參數列表)bash

function Foo() {
    getName = function () { alert (1); };
    return this;
}
Foo.getName = function () { alert (2);};
Foo.prototype.getName = function () { alert (3);};
var getName = function () { alert (4);};
function getName() { alert (5);}

//答案:
Foo.getName();//2
getName();//4
Foo().getName();//1
getName();//1
new Foo.getName();//2 new (Foo.getName)(); 因此這裏實際上將getName函數做爲了構造函數來執行
new Foo().getName();//3 (new Foo()).getName() 首先new有參數列表(18)跟點的優先級(18)是同級,同級的話按照從左向右的執行順序,因此先執行new有參數列表(18)再執行點的優先級(18),最後再函數調用(17)
new new Foo().getName();//3 new ((new Foo()).getName)(); 先初始化Foo的實例化對象,而後將其原型上的getName函數做爲構造函數再次new,因此最終結果爲3

複製代碼

4. 函數節流

window.onresize = throttleV2(myFunc, 50, 100);則意味着,50ms的間隔內連續觸發的調用,後一個調用會把前一個調用的等待處理掉,但每隔100ms至少執行一次。原理也很簡單,打時間tag,一開始記錄第一次調用的時間戳,而後每次調用函數都去拿最新的時間跟記錄時間比,超出給定的時間就執行一次,更新記錄時間。閉包

var throttleV2 = function(fn, delay, mustRunDelay){
 	var timer = null;
 	var t_start;
 	return function(){
 		var context = this, args = arguments, t_curr = +new Date();
 		clearTimeout(timer);
 		if(!t_start){
 			t_start = t_curr;
 		}
 		if(t_curr - t_start >= mustRunDelay){
 			fn.apply(context, args);
 			t_start = t_curr;
 		}
 		else {
 			timer = setTimeout(function(){
 				fn.apply(context, args);
 			}, delay);
 		}
 	};
 };

window.onresize = throttleV2(myFunc, 50, 100);


複製代碼
相關文章
相關標籤/搜索