call

Function.prototype.call2 = function(context) {
    context = context || window
    context.fn = this
    let args = Array.prototype.slice.call(arguments, 1)
    let result = context.fn(...args)
    delete context.fn
    return result
}

apply

Function.prototype.apply2 = function(context, args) {
    context = context || window
    context.fn = this
    let result = context.fn(...args)
    delete context.fn
    return result
}

bind

Function.prototype.bind2 = function (context) {
    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();
    return fBound;
}

new

function myNew() {
    let obj = Object.create(null)
    let fun = Array.prototype.shift.call(arguments)
    obj._proto_ = fun.prototype
    let result = fun.apply(obj, arguments)
    return typeof result === 'object' ? result : obj
}

Promise

class myPromise{
    let callbacks = []
    let state = 'pendding'
    let value = null
    constructor(fn){
   	fn(this._resolve.bind(this))
    }
    then(onFulfilled){
	if(this.state === 'pendding'){
	    this.callbacks.push(onFulfilled)
   	}else{
	    onFulfilled(this.value)
	}
	return this
    }
    _resolve(value){
	this.state = 'fulfilled'
	this.value = value
	this.callbacks.forEach(fn => fn(value))
    }
}

Promise.all