Object.is
Object.is = function(x, y) {
// SameValue algorithm
if (x === y) { // Steps 1-5, 7-10
// Steps 6.b-6.e: +0 != -0
return x !== 0 || 1 / x === 1 / y;
} else {
// Step 6.a: NaN == NaN
return x !== x && y !== y;
}
};复制代码
call
Function.prototype.myCall = 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 + ')');
var result = new Function('context', 'arguments', 'context.fn(' + args + ')')(context, arguments)
delete context.fn
return result;
}复制代码
bind
Function.prototype.bind = function(oThis) {
if (typeof this !== 'function') {
// closest thing possible to the ECMAScript 5
// internal IsCallable function
throw new TypeError('Function.prototype.bind - what is trying to be bound is not callable');
}
var aArgs = Array.prototype.slice.call(arguments, 1),
fToBind = this,
fNOP = function() {},
fBound = function() {
return fToBind.apply(this instanceof fNOP
? this
: oThis,
// 获取调用时(fBound)的传参.bind 返回的函数入参往往是这么传递的
aArgs.concat(Array.prototype.slice.call(arguments)));
};
// 维护原型关系
if (this.prototype) {
// Function.prototype doesn't have a prototype property
fNOP.prototype = this.prototype;
}
fBound.prototype = new fNOP();
return fBound;
};复制代码
节流 去抖
var throttleV1 = function(action, delay, mustRunDelay) {
var timer = null,
startTime;
return function() {
var self = this,
args = arguments,
currTime = new Date();
clearTimeout(timer);
if(!startTime) {
startTime = currTime;
}
if(currTime - startTime >= mustRunDelay) {
action.apply(self, args);
startTime = currTime;
}
else {
timer = setTimeout(function() {
action.apply(self, args);
}, delay);
}
};
};
var debounce = function(action, delay) {
var timer = null;
return function() {
var self = this,
args = arguments;
clearTimeout(timer);
timer = setTimeout(function() {
action.apply(self, args)
}, delay);
}
}复制代码
四舍五入-原生toFixed() 方法不准确
function toFixed(num, s) {
var times = Math.pow(10, s);
var des = num * times + 0.5;
des = parseInt(des, 10) / times;
return des + '';
}复制代码
小数相乘
function accMul(arg1, arg2) {
let m = 0,
s1 = arg1.toString(),
s2 = arg2.toString()
try {
m += s1.split('.')[1].length
} catch (e) {} // eslint-disable-line
try {
m += s2.split('.')[1].length
} catch (e) {} // eslint-disable-line
return Number(s1.replace('.', '')) * Number(s2.replace('.', '')) / Math.pow(10, m)
}复制代码
使对象拥有 iterator
var myObject = { a: 2,
b: 3 };
Object.defineProperty( myObject, Symbol.iterator, { enumerable: false,
writable: false,
configurable: true,
value: function() { var o = this;
var idx = 0;
var ks = Object.keys( o ); return {
next: function() { return {
value: o[ks[idx++]],
done: (idx > ks.length)
};
} };
} } );
// 手动遍历 myObject
var it = myObject[Symbol.iterator]();
it.next(); // { value:2, done:false }
it.next(); // { value:3, done:false }
it.next(); // { value:unde ned, done:true }
// 用 for..of 遍历 myObject
for (var v of myObject) { console.log( v );
}
// 2
// 3复制代码
数字转为ABC
function convertToTitle(n) {
let arr = []
while (n > 0) {
let c = ((n-1 ) % 26) + 65
arr.unshift(String.fromCharCode(c))
n = Math.floor((n - 1) / 26)
}
return arr.join('')
};复制代码
简单实现promise
function myPromise (fn) {
this.state = 'PENDING'
this.value = null
this.handlers = []
function resolve (result) {
var that = this
// 可以不加setTimeout , 加上只为了实现像原生一样resolve异步
// setTimeout(function(){
this.state = 'FULFILLED'
this.value = result
this.handlers.forEach(function (callback) {
callback( result);
})
// })
}
fn(resolve.bind(this) )
}
myPromise.prototype.then = function (onFulfilled) {
var self = this;
return new myPromise(function(resolve, reject) {
function handle(value){
var result = typeof onFulfilled === 'function' && onFulfilled(value) || value;
if( result && typeof result['then'] == 'function'){
result.then(function(value){
resolve(value);
});
}else {
resolve(value);
}
}
if (self.state === 'PENDING') {
self.handlers.push(handle);
}
if (self.state === 'FULFILLED') {
handle(self.value)
}
if (this.state === 'REJECTED') {
reject(self.value)
}
})
}复制代码