call、apply、bind使用方法及区别

首先,这三个都是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

https://blog.csdn.net/u010176097/article/details/80348447

https://www.jianshu.com/p/bc541afad6ee

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值