本帖最后由 逆风TO 于 2020-3-18 14:54 编辑
考查 thiscall、apply[JavaScript] 纯文本查看 复制代码 Function.prototype._call = function(ctx = window, ...args) {[/b] const fnKey = 'tmp_' + Date.now();
ctx[fnKey] = this;
const result = ctx[fnKey](...args);
delete ctx[fnKey];
return result;
};
// 第二个参数是数组
Function.prototype._apply = function(ctx = window, args = []) {
const fnKey = 'tmp_' + Date.now();
ctx[fnKey] = this;
const result = ctx[fnKey](...args);
delete ctx[fnKey];
return result;
};
let obj = { x: 1 };
function fn() {
console.log(this.x, arguments);
}
fn._call(obj, 1, 2, 3);
fn._apply(obj, [1, 2, 3]); bind[JavaScript] 纯文本查看 复制代码 Function.prototype._bind = function() {
const slice = [].slice;
const _fn = this;
const ctx = arguments[0];
const args = slice.call(arguments, 1);
if (typeof _fn !== 'function') {
throw new TypeError('Function.prototype.bind - ' +
'what is trying to be bound is not callable');
}
return function() {
const funcArgs = args.concat(slice.call(arguments));
return _fn.apply(ctx, funcArgs);
};
};
const obj = { x: 1 };
function A() {
console.log(this.x);
}
const fn = A._bind(obj);
fn();
new
[JavaScript] 纯文本查看 复制代码 function newObject(fn) {
const obj = {};
const res = fn.apply(obj, [].slice.call(arguments, 1));
return res instanceof Object ? res : obj;
}
function Con(a) {
this.a = a;
}
const obj = newObject(Con, 1);
链式调用
[JavaScript] 纯文本查看 复制代码 Number.prototype.add = function(num) {
num = +num;
if(num !== num) return Number(this);
return Number(this + num);
};
let n = 1;
n.add(1).add(2).add(3);
考查原型链
[JavaScript] 纯文本查看 复制代码 function instance_of(lhs, rhs) {
while (lhs) {
lhs = lhs.__proto__;
if (lhs === rhs.prototype) return true;
}
return false;
}
组合寄生继承
[JavaScript] 纯文本查看 复制代码 function Super(){}
function Sub() {
Super.call(this); // 继承自有属性
}
// 继承原型链上的属性和方法
Sub.prototype = Object.create(Super.prototype); // 继承原型链
Sub.prototype.constructor = Sub;
Object.create
[JavaScript] 纯文本查看 复制代码 if(!Object.create) {
Object.create = function(proto) {
function F(){}
F.prototype = proto;
return new F;
}
}
纯对象
[JavaScript] 纯文本查看 复制代码 function isPlainObject(obj) {
if (typeof obj !== 'object' || obj === null) return false;
var proto = obj;
while (Object.getPrototypeOf(proto) !== null) {
proto = Object.getPrototypeOf(proto);
}
return Object.getPrototypeOf(obj) === proto;
}
function A() {}
isPlainObject( new A ); // false
isPlainObject( new Object ); // true
isPlainObject( {} ); // true
判断类型
[JavaScript] 纯文本查看 复制代码 const type = 'Boolean Number String Function Array Date RegExp Object Error Symbol'
.split(' ')
.reduce((pre, name) => {
pre[`[object ${name}]`] = name.toLowerCase();
return pre;
}, {});
function toType( obj ) {
if ( obj == null ) {
return obj + '';
}
return typeof obj === 'object' || typeof obj === 'function' ?
type[ Object.prototype.toString.call( obj ) ] || 'object' :
typeof obj;
}
toType(/xxx/) // regexp
考查闭包柯里化
[JavaScript] 纯文本查看 复制代码 function curry(fn, ...args) {
if(args.length >= fn.length) {
return fn.apply(null, args);
}
return (...args2) => curry(fn, ...args, ...args2);
}
const add = curry(function(a, b, c) {
return a + b + c;
});
add(1, 2, 3);
add(1)(2)(3);
add(1, 2)(3);
add(1)(2, 3);
考查性能意识防抖[JavaScript] 纯文本查看 复制代码 function debounce(fn, delay) {[/b] let timer = null;
return function() {
// 中间态一律清除掉
timer && clearTimeout(timer);
// 只需要最终的状态,执行
timer = setTimeout(() => fn.apply(this, arguments), delay);
};
}
节流[JavaScript] 纯文本查看 复制代码 function throttle(fn, delay) {[/b] let timer, lastTime;
return function() {
const now = new Date().getTime();
const space = now - lastTime; // 间隔时间
if( lastTime && space < delay ) { // 为了响应用户最后一次操作
// 非首次,还未到时间,清除掉计时器,重新计时。
timer && clearTimeout(timer);
// 重新设置定时器
timer = setTimeout(() => {
lastTime = now; // 不要忘了记录时间
fn.apply(this, arguments);
}, delay);
return;
}
// 首次或到时间了
lastTime = now;
fn.apply(this, arguments);
};
} 事件代理
[JavaScript] 纯文本查看 复制代码 function delegate(ele, selector, type, fn) {
function callback(e) {
e = e || window.event;
const target = e.target || e.srcElement;
if( ele.contains(target) ) {
fn.call(target, e);
}
}
ele.addEventListener(type, callback, false);
}
delegate(document.querySelector('body'), 'button', 'click', function () {
console.log('bingo');
});
限制并发数
[JavaScript] 纯文本查看 复制代码 function sendRequest(urls, max, callback) {
let last = performance.now();
let len = urls.length;
let limit = max; // 控制并发数
let cnt = 0; // 累积执行任务数
let res = []; // 有序存储执行结果
const tasks = urls.map((url, index) => () => fetch(url)
.then(data => {
res[index] = data;
})
.catch(reason => {
res[index] = reason;
})
.finally(() => {
if( ++cnt === len ) return callback(res);
++limit;
doTasks();
}));
doTasks();
function doTasks() {
while( limit && tasks.length ) {
--limit;
let task = tasks.shift();
task();
console.log(`执行间隔:${performance.now() - last}`);
}
}
}
// 模拟 fetch
function fetch(url) {
return new Promise(function (resolve, reject) {
let good, bad;
const time = 3000;
good = setTimeout(function () {
clearTimeout(bad);
let data = `resolve: ${url}`;
resolve(data);
console.log(data);
}, Math.random() * time);
bad = setTimeout(function () {
clearTimeout(good);
let reason = `reject: ${url}`;
reject(reason);
console.log(reason);
}, Math.random() * time);
});
}
// 测试
sendRequest([1,2,3,4,5,6,7,8,9,10], 5, (res) => console.log('all done:' + res));
|
|