call apply bind
区别
call
js
fn.call(null, params); // 参数列表
fn.call(null, params); // 参数列表
当第一参数为 null
或 undefined
时,默认指向 window
对象;
apply
js
fn.call(null, array); // 数组
fn.call(null, array); // 数组
当第一参数为 null
或 undefined
时,默认指向 window
对象;
bind
js
fn.bind(null, params)(); // 参数列表
fn.bind(null, params)(); // 参数列表
当第一参数为 null
或 undefined
时,默认指向 window
对象; 返回值为改变了 this
的函数
源码实现
call
JS
Function.prototype._call = function(obj) {
var obj = obj || window;
obj.p = this;
var newArguments = [];
for(var i = 1; i < arguments.length; i++) {
newArguments.push('arguments[' + i + ']');
}
var result = eval('obj.p(' + newArguments + ')');
delete obj.p;
return result;
}
// 展开运算符实现简易版
Function.prototype._call = function (obj, ...args) {
const newObj = obj || globalThis;
newObj.p = this;
const result = newObj.p(...args);
delete newObj.p;
return result;
};
Function.prototype._call = function(obj) {
var obj = obj || window;
obj.p = this;
var newArguments = [];
for(var i = 1; i < arguments.length; i++) {
newArguments.push('arguments[' + i + ']');
}
var result = eval('obj.p(' + newArguments + ')');
delete obj.p;
return result;
}
// 展开运算符实现简易版
Function.prototype._call = function (obj, ...args) {
const newObj = obj || globalThis;
newObj.p = this;
const result = newObj.p(...args);
delete newObj.p;
return result;
};
apply
JS
Function.prototype._apply = function(obj, arr) {
var obj = obj || window;
var result;
obj.p = this;
if(!arr) {
result = obj.p();
} else {
var newArguments = [];
for(var i = 1; i < arguments.length; i++) {
newArguments.push('arguments[' + i + ']');
result = eval('obj.p(' + newArguments + ')');
}
delete obj.p;
return result;
}
Function.prototype._apply = function(obj, arr) {
var obj = obj || window;
var result;
obj.p = this;
if(!arr) {
result = obj.p();
} else {
var newArguments = [];
for(var i = 1; i < arguments.length; i++) {
newArguments.push('arguments[' + i + ']');
result = eval('obj.p(' + newArguments + ')');
}
delete obj.p;
return result;
}
bind
JS
Function.prototype._bind = function (obj) {
var _this = this;
// 获取
var arr = Array.prototype.slice.call(arguments, 1);
var Fn = function() {
// 将所有参数转为数组
var arr2 = Array.prototype.slice.call(arguments);
var arrSum = arr.concat(arr2);
if(this instanceof Fn) {
_this.apply(this, arrSum);
} else {
_this.apply(obj, arrSum);
}
}
Fn.prototype = _this.prototype;
return Fn;
}
Function.prototype._bind = function (obj) {
// 判断调用对象是否为函数
if (typeof this !== "function") {
throw new TypeError("Error");
}
// 获取参数
const args = [...arguments].slice(1),
fn = this;
return function Fn() {
// 根据调用方式,传入不同绑定值
return fn.apply(this instanceof Fn ? new fn(...arguments) : context, args.concat(...arguments));
}
}
Function.prototype._bind = function (obj) {
var _this = this;
// 获取
var arr = Array.prototype.slice.call(arguments, 1);
var Fn = function() {
// 将所有参数转为数组
var arr2 = Array.prototype.slice.call(arguments);
var arrSum = arr.concat(arr2);
if(this instanceof Fn) {
_this.apply(this, arrSum);
} else {
_this.apply(obj, arrSum);
}
}
Fn.prototype = _this.prototype;
return Fn;
}
Function.prototype._bind = function (obj) {
// 判断调用对象是否为函数
if (typeof this !== "function") {
throw new TypeError("Error");
}
// 获取参数
const args = [...arguments].slice(1),
fn = this;
return function Fn() {
// 根据调用方式,传入不同绑定值
return fn.apply(this instanceof Fn ? new fn(...arguments) : context, args.concat(...arguments));
}
}