本篇文章旨在总结javascript的部分方法的模拟实现,不定期积累更新,各路大神如有更加完美的实现,还望不吝赐教
1.Function.prototype.call实现
Function.prototype.myCall = function (context){
if(!context) context = window;
context.fn = this;
var args = [];
for(var i = 1;i<arguments.length;i++){
// 避免eval解析字符串参数为变量
args.push('arguments[' + i + ']')
}
var result = eval('context.fn(' + args + ')');
delete context.fn;
return result;
}
2.Function.prototype.apply实现
Function.prototype.myApply = function (context, args){
if(!context) context = window;
if(!(args instanceof Array)) args = [];
context.fn = this;
var newArgs = args.map(function(val, index){
// 同上
return 'args[' + val + ']';
})
var result = eval('context.fn(' + args + ')');
delete context.fn;
return result;
}
3.Function.prototype.bind实现
Function.prototype.myBind = function (context){
context = context || window;
var self = this;
var slice = Array.prototype.slice;
var args = slice.call(arguments, 1);
var fbound = function(){
var bindArgs = slice.call(arguments);
//解决bind绑定后返回的函数当构造函数使用时候 this会失效
self.apply(this instanceof self ? this : context, args.concat(bindArgs))
}
//作为构造函数使用,需继承其原型上面的方法
fbound.prototype = Object.create(self.prototype);
return fbound;
}
4.new操作符的实现
Reflect.construct = function(target, args){
var obj = Object.create(target.prototype);
var res = target.apply(obj, args);
// 处理构造函数有返回值且返回值为对象的情况
return typeof res === 'object' ? res : obj;
}
5.Object.is实现
修正了===对于 -0 === +0 和 NaN === NaN的误判
function is(x, y){
if(x === y){
return x !== 0 || y !== 0 || 1/x === 1/y
}else{
return x !== x && y !== y
}
}
6.instanceof实现
function _instanceOf(left, right){
if(typeof left !== 'object' || left === null ) return false;
let proto = Object.getPrototypeOf(left);
for(;;){
if(proto === null) return false;
if(proto === right.prototype) return true;
proto = Object.getPrototypeOf(proto);
}
}
7.Object.assign实现
Object.myAssign = function(origin, ...args){
function assignValue(left, right){
if(typeof right !== 'object' || typeof right === null) return;
for(let key in right){
if(right.hasOwnProperty(key)){
left[key] = right[key]
}
}
}
args.forEach(e => {
assignValue(origin, e);
})
return origin;
}
8.async/await实现
function asyncToGenerator(generatorFun){
return function(){
const gen = generatorFun.apply(this, arguments);
return new Promise((resolve, reject) => {
function step(key, val){
let result = null;
try{
result = gen[key](val);
}catch(err){
return reject(err);
}
const {done, value} = result;
if(done){
return resolve(value);
}else{
return Promise.resolve(value).then(val => {
step('next', val)
}, err => {
step('throw', err);
})
}
}
step('next');
})
}
}
//测试
function sleep(time){
return new Promise((resolve, reject)=>{
setTimeout(() => {
resolve(time)
}, time);
})
}
function *f(ms){
let s1 = yield sleep(ms);
console.log(s1)
let s2 = yield sleep(s1);
console.log(s2)
let s3 = yield sleep(s2);
return 'finish'
}
const run = asyncToGenerator(f);
run(2000).then(res => {
console.log(res)
})