js中call()与apply()方法

本文详细介绍了JavaScript中call与apply方法的区别与应用。通过具体示例讲解如何改变函数内部this的指向,展示如何利用这两个方法进行函数继承及解决实际问题。

菜鸟级别的选手,学习+意会。欢迎指正

参考文章

http://uule.iteye.com/blog/1158829
http://blog.youkuaiyun.com/myhahaxiao/article/details/6952321

语法规则

call方法:
语法:call([thisObj[,arg1[, arg2[, [,.argN]]]]])

apply方法:
语法:apply([thisObj[,argArray]])

第一个参数。就是你用来替换函数中的this的那个对象。

由于apply,call是定义在Function.prototype上的,所以,只要是函数都可以调用这两个方法(原型链)。

小例子

    var obj = {
        name : 'hanker'
    };
    function f(a,b){
        console.log(this.name);  //hanker
        console.log(a); //1
        console.log(b); //2
    }
    f.call(obj,1,2);
   
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

作用:Apply,与call的作用都是一样:更改函数内部的this,让它指向第一个参数。

上面的小例子展示了call的基本用法。前面f视为一个对象,他使用对象的call()方法,参数为3个。上面小例子中只有一个参数
我们可以粗劣的把f.call(obj);视作执行f(1,2);,有了call方法后,f函数中所有的this都指向了obj对象。

call与apply区别

var obj = {
        name : 'hanker'
    };
    function f(a,b){
        console.log(this.name);  //hanker
        console.log(a); //1
        console.log(b); //2
    }
    f.apply(obj,[1,2]);
   
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

两者区别在于参数的写法不同.上面的代码和小例子的代码作用一样
apply只有两个参数,而call可写多个参数。apply()方法的第一个参数为一个对象,第二个参数为一个数组或类数组对象(由以前的知识可知函数即对象,函数也有自己的方法)。
为什么要同时有 call 和 apply 方法呢?
在js中有一个只存在于函数中的类数组对象arguments.在一些情况下可以直接使用apply()方法

常用实例

<script type="text/javascript">
    /*定义一个人类*/
    function Person(name,age)
    {
        this.name=name;
        this.age=age;
    }
    /*定义一个学生类*/
    function Student(name,age,grade)
    {
        Person.apply(this,arguments);
        this.grade=grade;
    }
    //创建一个学生类
    var student=new Student("qian",21,"一年级");
    //测试
                   alert("name:"+student.name+"\n"+"age:"+student.age+"\n"+"grade:"+student.grade);
    //name:qian  age:21  grade:一年级
</script>
   
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

从上面例子看:
1.代码是从new Student(“qian”,21,”一年级”);这一句开始执行的。
2.用new创建了一个新对象student. 同时也调用了函数function Student(name,age,grade)
3.运行Person.apply(this,arguments); ,可以视作Person(arguments );在apply方法里,其中 this指向了新创建的对象。于是Person函数中的this就指向了student.(arguments就是一个类数组对象)。于是Student就有了Person的属性和方法。

从某些特性来看,这就是js中的继承。

进一步利用

1.利用Math.max求数组中的最大值
Math.max 参数里面不支持Math.max([param1,param2]) 也就是数组。
可以使用

var min = Math.min.apply(null, [10,8,9,7,1]);
console.log(min);
   
  • 1
  • 2
  • 1
  • 2

2.判断数据类型
借用了Object.prototype.toString

var a = [];      
  var b = function(){};
  var c = {};
  var d = null;
  var e = 1;
  console.log( Object.prototype.toString.call(a) );  //[object Array]
  console.log( Object.prototype.toString.call(b) );  //[object Function]
  console.log( Object.prototype.toString.call(c) );  //[object Object]
  console.log( Object.prototype.toString.call(d) );  //[object Null]
  console.log( Object.prototype.toString.call(e) );  //[object Number]
   
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

3.实现字符串的翻转

 var str = 'abcdefghijk';
  String.prototype.reverse = function(){
    return Array.prototype.reverse.call(this.split('')).join('');
  }
  console.log( str.reverse() );
   
  • 1
  • 2
  • 3
  • 4
  • 5
  • 1
  • 2
  • 3
  • 4
  • 5

注意:上面两个运用了原型链的知识。

(function () {('pre.prettyprint code').each(function () { var lines = (this).text().split(\n).length;var numbering = $('
    ').addClass('pre-numbering').hide(); (this).addClass(hasnumbering).parent().append( numbering); for (i = 1; i
    评论
    成就一亿技术人!
    拼手气红包6.0元
    还能输入1000个字符
     
    红包 添加红包
    表情包 插入表情
     条评论被折叠 查看
    添加红包

    请填写红包祝福语或标题

    红包个数最小为10个

    红包金额最低5元

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

    抵扣说明:

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

    余额充值