bind
基础版
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
if(Function.prototype.bind === undefined){
console.log('您的浏览器不支持bind方法! 开始使用手写bind功能!');
Function.prototype.bind = function(obj){
var arg1 = [].slice.call(arguments,1); // 解释一下骚操作,用 arg1 保留了当函数调用bind方法时候传入的参数,因为arguments是类数组对象,我们借用了数组的slice方法
var fun = this; // fun —> bind调用者(也就是某个函数)
return function(){
fun.apply(obj,arg1.concat([].slice.call(arguments,1)));
// 这里返回了一个闭包函数, 里面可以使用 obj , arg1 , fun 这些变量,配合起来实现了bind
}
}
}else{
console.log('您的浏览器支持bind方法!')
}
健壮版
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
if (!Function.prototype.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 && oThis
? this
: oThis || window,
aArgs.concat(Array.prototype.slice.call(arguments)));
};
fNOP.prototype = this.prototype;
fBound.prototype = new fNOP();
return fBound;
};
}
promise
最简单版
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
function Promise(excutor) {
const self = this
self.onResolvedCallback = []
function resolve(value) {
setTimeout(() => {
self.data = value
self.onResolvedCallback.forEach(callback => callback(value))
})
}
excutor(resolve.bind(self))
}
Promise.prototype.then = function(onResolved) {
const self = this
return new Promise(resolve => {
self.onResolvedCallback.push(function() {
const result = onResolved(self.data)
if (result instanceof Promise) {
result.then(resolve)
} else {
resolve(result)
}
})
})
}