深入理解call()与apply()方法

前面的话

ECAMScript 3 给Function的原型定义两个方法。Function.prototype.call()与
Function.prototype.apply()方法。这两个方法尤为重要,熟练掌握这两个方法,
是真正成为前端程序员重要的一步。

●call()与apply()的定义

函数是也是对象,对象就有方法和属性,每个函数都可以使用call()与apply()方法。
Function.apply(obj,args);
obj: 这是一个对象,将代替Function里面的this对象
args:这是一个数组,它将作为参数传递给Function(args —> arguments)

call与apply()的区别只是参数列表不同,作用都是相同的。
Function.call(obj,value1,value2…)
obj: 这是一个对象,将代替Function里面的this对象
value1,value2…: 是参数列表

●call()与apply()的作用:改变this指向

当传入的是null时,this指向为window,传入其他的对象this则指向传入的对象

 var obj1 = {
        name: 'wan'
    };
    var obj2 = {
        name: 'li'
    };
    window.name = 'yang';
    function getName() {
        console.log(this.name);
    }
    getName.call(null);// yang
    getName.call(obj1);// wan
    getName.call(obj2);// li
 

apply实例:

function Person(name, age, sex) {
        this.name = name;
        this.age = age;
        this.sex = sex;
    }
    function Student(name, age, sex, grad) {
        Person.apply(this,arguments);
        this.grad = grad;
    }
    var std = new Student('wan', 20, '女', 90);
    console.log('name:'+ std.name  + ' age:' + std.age  + ' sex:' + std.sex  + ' grad' + std.grad);

我们会发现结果std对象的name,age,sex我们都可以得到。就是因为apply()方法的作用,它改变了this的指向.
Person.apply()这条语句就一定会执行Person构造函数,而Student构造函数里面的this指向的是student这个对象,apply方法
里面传入了这个this,此时相当于Person构造函数里面的this被Student构造函数里面的this(student对象)所代替。

call()实例:

只需将上例的Person.apply(this,arguments)改为Person.call(this,name,age,sex)即可。

function Person(name, age, sex) {
        this.name = name;
        this.age = age;
        this.sex = sex;
    }
    function Student(name, age, sex, grad) {
        Person.call(this,name,age,sex);
        this.grad = grad;
    }
    var std = new Student('wan', 20, '女', 90);
    console.log('name:'+ std.name  + ' age:' + std.age  + ' sex:' + std.sex  + ' grad' + std.grad);

call()方法与apply()方法基本一样,就是参数列表不一样,apply(obj,args)传入的是一个数组,而call(obj,value1,value2…)方法 传入的是一个一个的值。

●apply()方法的一些妙用

上例:我们可以发现apply()的第二个参数是一个数组,而Person()构造函数里面的形参是一个一个的值。那么apply可以将一个数组 解析为一个一个的参数。利用这一特性,可以有以下高效方法。

1:Math.max()可以实现得到数组最大值

Math.max()的参数是不支持数组的,但是它支持Math.max(value1,value2…),利用apply()方法的特性可以实现。

 Math.max.apply(null,[13, 45, 89, 90]);// 90

apply()方法将数组解析为一个一个参数出入Math.max()方法

2: Math.min()可以实现得到数组最小值

   Math.min.apply(null,[13, 45, 89, 90]);// 13

3: Array.prototype.push可以将一个数组添加到另一个数组的尾部

    var arr1 = [0, 1, 2];
    var arr2 = [3, 4, 5];
    console.log( Array.prototype.push.apply(arr1,arr2));
    console.log(arr1);// [0,1,2,3,4,5] arr1向后面追加了arr2   
●总结

掌握一个知识点就要多理解,多敲代码,多看看别人的总结。第三部分apply的妙用参考阮一峰老师的‘es6标准入门’这本书。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值