这里的模拟实现,目的是在于提升对重要函数的理解
1 call、apply
2 bind
3 reduce
4 promise
call: 在调用的时候,修改调用对象的this指向,可以附带多个参数,可以有返回值
模拟思路:主要是修改this的指向,让其指向call的第一个参数
实现方式:让调用的函数对象作为传入的第一个参数的属性,执行完成之后删除它
// call
Function.prototype.call2 = Function.prototype.call2 || function (context) {
var context = context || window;
context.fn = this;
var args = [];
for(var i = 1, len = arguments.length; i < len; i++) {
args.push('arguments[' + i + ']');
}
var result = eval('context.fn(' + args +')');
delete context.fn
return result;
}
// apply
Function.prototype.apply = Function.prototype.apply || function (context, arr) {
var context = Object(context) || window;
context.fn = this;
var result;
if (!arr) {
result = context.fn();
}
else {
var args = [];
for (var i = 0, len = arr.length; i < len; i++) {
args.push('arr[' + i + ']');
}
result = eval('context.fn(' + args + ')')
}
delete context.fn
return result;
}
需要解决的几个问题:
// bind
Function.prototype.bind2 = Function.prototype.bind2 || function (context) {
if (typeof this !== "function") {
throw new Error("Function.prototype.bind - what is trying to be bound is not callable");
}
var self = this; // 保存最原始的函数对象
var args = Array.prototype.slice.call(arguments, 1);//预置参数
var fNOP = function () {};
var fBound = function () {
var bindArgs = Array.prototype.slice.call(arguments);
return self.apply(this instanceof fNOP ? this : context, args.concat(bindArgs));
}
fNOP.prototype = this.prototype;
fBound.prototype = new fNOP(); // 继承 fNOP
return fBound;
}
基本应用
//Array.prototype.reduce
var numbers = [65, 44, 12, 4];
function getSum(total, num) {
return total + num;
}
console.log(numbers.reduce(getSum)) // 65 + 44 + 12 + 4 = 125
可以看出 reduce 是将数组中的每个元素依次在其传入的函数中执行,执行结果作为下一次执行的第一个参数。
模拟实现
// 第一版 reduce 模拟
function myReduce(func, initData) {
let result = this[0], start = 1;
if(typeof initData !== 'undefined') {
result = initData;
start = 0;
}
for(let i = start;i<this.length;i++) {
result = func(result, this[i])
}
return result;
}
// test
var numbers = [65, 44, 12, 4];
function getSum(total, num) {
return total + num;
}
console.log(myReduce.call(numbers, getSum)) // 125
time:2018.10.09
项目中很多地方用到 promise 的地方,比如按需加载 import 返回的是 promise,请求数据 fetch、axios 返回的也是 promise,还有 generator, async 与 promise 的结合使用等
先看看基本使用情况
// promise 使用
let promise = new Promise(function(resolve, reject) {
console.log('Promise');
resolve();
});
promise.then(function() {
console.log('resolved.');
});
console.log('Hi!');
// Promise
// Hi!
// resolved
特点:
resolve(params)
传递模拟实现
暂时不做