首先,这三个都是Function函数对象自带的非继承来的方法,都可以用来改变函数运行时this的指向(调用函数时,this指向指定的对象thisObj)
(1)语法:
/*apply()方法*/
function.apply(thisObj, [argArray])
/*call()方法*/
function.call(thisObj, arg1, arg2, ..., argN);
/*bind()方法*/
function.bind(thisObj, arg1, arg2, ..., argN);
注意:当thisObj传参为null或undefined时,this指向为Global对象(浏览器中即为Window对象);
(2)定义:
apply:调用一个对象的一个方法,用另一个对象替换当前对象。例如:B.apply(A, arguments);即A对象应用B对象的方法。
call:调用一个对象的一个方法,用另一个对象替换当前对象。例如:B.call(A, args1,args2);即A对象调用B对象的方法
bind:返回改变上下文this后的函数以及bind接收的参数列表的使用。
(3)区别:
1、call和apply功能是一样的,都是在特定作用域中调用函数,区别在于传参。除了相同的第一个参数均为this指向对象thisObj,call另外接收多参数,而apply另外只接收一个array对象。
2、bind和call类似,区别在于bind返回的是对应函数, 便于稍后调用; apply, call则是立即调用(使用上有区别)。
(4)使用
call / apply基本用法:
var xiaoming = {
name: 'xiaoming',
age: '18'
};
function getInfo () {
console.log('my name is ' + this.name + ', I am ' + this.age + ' years old~');
}
getInfo.call(xiaoming); // my name is xiaoming, I am 18 years old~
getInfo.apply(xiaoming); // my name is xiaoming, I am 18 years old~
另外,使用apply和call可以实现继承:
function A1 () {
this.addNum = function (num1, num2) {
console.log(num1 + num2);
};
}
function A2 () {
this.subNum = function (num1, num2) {
console.log(num1 - num2);
};
}
function A (num1, num2) {
A1.call(this); // A1.apply(this);
A2.call(this); // A2.apply(this);
}
var a = new A();
a.addNum(3, 1); // 4
a.subNum(3, 1); // 2
bind用法(bind返回值是函数,且调用时的传参是在bind中参数基础往后排):
function A1 (x, y, z) {
console.log(x, y, z);
}
var A = A1.bind(null, 1);
A1(1, 2, 3); // 1 2 3
A1.call(null, 1, 2); // 1 2 undefined
A(1, 2, 3) // 1 1 2
A(2, 3) // 1 2 3
var xiaoming = {
name: 'xiaoming',
age: '18'
};
function getInfo () {
console.log('my name is ' + this.name + ', I am ' + this.age + ' years old~');
}
var info = getInfo.bind(xiaoming);
info(); // my name is xiaoming, I am 18 years old~
// 低版本浏览器中实现bind
if (!Function.prototype.bind) {
Function.prototype.bind = function () {
var self = this, // 保存原函数
context = [].shift.call(arguments), // 保存需要绑定的this上下文
args = [].slice.call(arguments); // 剩余的参数转为数组
return function () { // 返回一个新函数
self.apply(context, [].concat.call(args, [].slice.call(arguments)));
}
}
}
(5)应用
- 求数组中的最大和最小值
var arr = [1,2,3,4,5]
var max = Math.max.apply(null,arr) // 5
var min = Math.min.apply(null,arr) // 1
- 数组合并
var arr1 = [1,2,3];
var arr2 = [4,5,6];
var total = [].push.apply(arr1, arr2); // 6(返回数组长度)
// var total = Array.prototype.push.apply(arr1,arr2); //6(返回数组长度)
- 将类数组转化为数组
Array.prototype.slice.call(arrayLike)
- 判断变量类型
function isArray(obj){
return Object.prototype.toString.call(obj) == '[object Array]';
}
isArray([]) // true
- 利用call和apply做继承
function Father (name, feature) {
this.lastName = name;
this.bigEyes = true;
this.getInfo = function () {
console.log('lastName: ' + this.lastName + ', bigEyes: ' + this.bigEyes);
}
}
function Son () {
Father.apply(this, arguments);
}
var son = new Son('Wang', true);
son.getInfo() // lastName: Wang, bigEyes: true
- 使用 log 代理 console.log
function log(){
console.log.apply(console, arguments);
}
// 当然也有更方便的 var log = console.log
参考文章:
https://blog.csdn.net/qq_40963664/article/details/83817781