fun.call(thisArg, arg1, arg2, ...)
fun.apply(thisArg, [arg1, arg2], ...)
- 用于动态改变函数运行时,函数内容的this指向,和传入参数值。
fun.bind(thisArg, arg1,arg2)
- bind()方法创建一个新的函数,在bind()被调用时,这个新函数的this被bind的第一个参数指定,其余的参数将作为新函数的参数供调用时使用。
var module = {
x: 42,
getX: function() {
console.log('this', this)
return this.x;
}
}
var unboundGetX = module.getX;
console.log(module.getX) // 直接是对函数的引用, this没有指定,this 为 window
console.log(module.getX()) // 使用对象module调用函数,所以this就是module
console.log(unboundGetX()); // The function gets invoked at the global scope
// expected output: undefined
var boundGetX = unboundGetX.bind(module);
console.log(boundGetX());
// expected output: 42
bind VS call/apply
- 一个函数被 call/apply 的时候,会直接调用
-
bind 会创建一个新函数
当这个新函数被调用时,bind() 的第一个参数将作为它运行时的 this,之后的一序列参数将会在传递的实参前传入作为它的参数。
使用apply实现bind
Function.prototype.bind = function(context) {
if(typeof this !== "function"){
throw new TypeError("not a function");
}
let self = this;
let args = [...arguments].slice(1); // args是arguments删除了第一参数的
function Fn() {};
Fn.prototype = this.prototype;
// 新定义了一个bound方法
let bound = function() {
let arg = [...args, ...arguments]; //bind传递的参数和函数调用时传递的参数拼接
context = this instanceof Fn ? this : context || this; // 判断执行上下文
return self.apply(context, arg );
}
//原型链
bound.prototype = new Fn();
return bound;
}
var name = 'Jack';
function person(age, job, gender){
console.log(this.name , age, job, gender);
}
var Pony = {name : 'Pony'};
let result = person.bind(Pony, 52, 'enginner')('male');
另一种简洁实现
Function.prototype._bind = function(){
var self = this //原函数
var context = [].shift.call(arguments) //this上下文
var args = [].slice.call(arguments) //参数
return function(){
self.apply(context, args.concat([].slice.call(arguments)))
}
}
网友评论