值对比
const toString = x => Object.prototype.toString.call(x)
const isObject = x => toString(x) === '[object Object]'
const isArray = x => toString(x) === '[object Array]'
function isSameValue (a, b) {
if (toString(a) !== toString(b)) {
return false
}
if (isObject(a)) {
return isSameObject(a, b)
}
if (isArray(a)) {
return isSameArray(a, b)
}
return a === b
}
function isSameObject (obj1, obj2) {
const keys1 = Object.getOwnPropertyNames(obj1)
const keys2 = Object.getOwnPropertyNames(obj2)
if (keys1.length !== keys2.length) {
return false
}
const len = keys1.length
for (var i = 0; i < len; i++) {
const key = keys1[i]
if (!isSameValue(obj1[key], obj2[key])) {
return false
}
}
return true
}
function isSameArray (xs1, xs2) {
const len1 = xs1.length
const len2 = xs1.length
if (len1 !== len2) {
return false
}
for (let i = 0; i < len1; i++) {
if (!isSameValue(xs1[i], xs2[i])) {
return false
}
}
return true
}
手写call、apply、bind
Function.prototype.myCall = function(context, ...args) {
if (typeof context === 'undefined' || context === null) {
context = window
}
let fnSymbol = Symbol()
context[fnSymbol] = this
let fn = context[fnSymbol](...args)
delete context[fnSymbol]
return fn
}
Function.prototype.myApply = function(context, args) {
if (typeof context === 'undefined' || context === null) {
context = window
}
let fnSymbol = Symbol()
context[fnSymbol] = this
let fn = context[fnSymbol](...args)
return fn
}
Function.prototype.myBind = function(context) {
if (typeof context === "undefined" || context === null) {
context = window
}
self = this
return function(...args) {
return self.apply(context, args)
}
}
promise简版
function MyPromise (fn) {
let _this = this
_this._status = 'pending'
_this._successFn = null
_this._failFn = null
fn(resolve.bind(this), reject.bind(this))
function resolve(params) {
if (_this._status === 'pending') {
_this._status = 'success'
_this._successFn(params)
}
}
function reject() {
if (_this._status === 'pending') {
_this._status = 'fail'
_this._failFn(params)
}
}
}
MyPromise.prototype.then = function (full, fail) {
this._successFn = full
this._failFn = fail
}
promise链式
function MyPromise(executor) {
let _this = this;
_this._status = 'pending';
_this._failFn = undefined;
_this._successFn = undefined;
_this.result = undefined;
setTimeout(_ => {
executor(_this.resolve.bind(_this), _this.reject.bind(_this));
})
}
MyPromise.prototype.then = function(full, fail) {
let newPromi = new MyPromise(_ => {});
this._successFn = full;
this._failFn = fail;
this.successDefer = newPromi.resolve.bind(newPromi);
this.failDefer = newPromi.reject.bind(newPromi);
return newPromi
};
MyPromise.prototype.resolve = function(params) {
let _this = this;
if (_this._status === 'pending') {
_this._status = 'success';
if (!_this._successFn) return;
let result = _this._successFn(params);
if (result && result instanceof MyPromise) {
result.then(_this.successDefer, _this.failDefer);
return ''
}
_this.successDefer(result)
}
}
MyPromise.prototype.reject = function(params) {
let _this = this;
if (_this._status === 'pending') {
_this._status = 'fail';
if (!_this._failFn) return;
let result = _this._failFn(params);
if (result && result instanceof MyPromise) {
result.then(_this.successDefer, _this.failDefer);
return ''
}
_this.successDefer(result)
}
}