1.apply()方法

apply方法能劫持另外一个对象的方法,继承另外一个对象的属性。

  Function.apply(obj,args)方法能接收两个参数

    obj:这个对象将代替Function类里this对象

    args:这个是数组,它将作为参数传给Function(args-->arguments)

使用apply()方法时可以直接将当前函数的arguments对象作为apply的第二个参数传入

(1)apply()方法可实现继承

eg:function Person(name,age){   //定义一个类,人类

this.name=name;     //名字  
    this.age=age;       //年龄 
    this.sayhello=function(){console.log("hello")};

function
Print(){            //显示类的属性 
    this.funcName="Print"; 
    this.show=function(){      
        var msg=[];
        for(var key in this){ 
            if(typeof(this[key])!="function"){
                msg.push([key,":",this[key]].join(""));
            }
        } 
        console.log(msg.join(" "));
    };

function Student(name,age,grade,school){    //学生类 
    Person.apply(this,arguments);
    Print.apply(this,arguments);
    this.grade=grade;                //年级 
    this.school=school;                 //学校 

var p1=new Person("jake",10);
p1.sayhello(); //hello
var s1=new Student("tom",13,6,"清华小学");
s1.show(); //name:tom age:13 funcName:Print grade:6 school:清华小学
s1.sayhello(); //hello
console.log(s1.funcName); //Print

学生类本来不具备任何方法,但是在Person.apply(this,arguments)后,它就具备了Person类的sayhello方法和所有属性。在Print.apply(this,arguments)后就自动得到了show()方法。

(2) apply()方法可以将参数数组默认的转换为参数列表

我们先从Math.max()函数说起,Math.max后面可以接任意个参数,最后返回所有参数中的最大值。

eg: Math.max(5,8)  //8

  Math.max(5,7,9,3,1,6)  //9

但是在很多情况下,我们需要找出数组中最大的元素。
var arr=[5,7,9,1]
console.log(Math.max(arr))    // NaN  这个方法无法实现

需要按如下所示的方法才可以实现:

eg:function getMax(arr){
    var arrLen=arr.length;
    for(var i=0,ret=arr[0];i<arrLen;i++){
        ret=Math.max(ret,arr[i]);       
    }
    return ret;
}

这样写麻烦而且低效。如果用 apply呢,看代码:
function getMax2(arr){
    return Math.max.apply(Math,arr);
}
两段代码达到了同样的目的,但是getMax2却更高效简洁。这里主要是由于apply可以将一个数组默认的转换为一个参数列表(即可以将数组[param1,param2,param3] 转换为 param1,param2,param3) ,如果让我们用程序来实现将数组的每一个项来转换为参数列表,像getMax方法一样会比较麻烦。借助apply的这点特性,就有了更加高效的解决方法如getMax2方法所示。

再比如数组的push方法。
var arr1=[1,3,4];
var arr2=[3,4,5];
如果我们要把 arr2展开,然后一个一个追加到arr1中去,最后让arr1=[1,3,4,3,4,5]
arr1.push(arr2)显然是不行的。
因为这样做会得到[1,3,4,[3,4,5]]

我们只能用一个循环去一个一个的push(当然也可以用arr1.concat(arr2),但是concat方法并不改变arr1本身,而是创建了一个新的数组)
var arrLen=arr2.length
for(var i=0;i<arrLen;i++){
    arr1.push(arr2[i]);
}

自从有了Apply,事情就变得如此简单
Array.prototype.push.apply(arr1,arr2) 或者 arr1.push.apply(arr1,arr2);

2.call()方法

call()方法与apply()方法的功能是一样的,只不过是参数列表不一样。如 func.call(func1,var1,var2,var3)对应的apply写法为:func.apply(func1,[var1,var2,var3])

Function.call(obj,[param1[,param2[,…[,paramN]]]])
obj:这个对象将代替Function类里this对象
params:这个是一个参数列表

eg:function Animal(){

  this.name = "Animal";
  this.showName = function(){
  console.log(this.name); }
}

function Cat(){
  this.name = "Cat";
  this.sayWorld=function(){
    console.log("hello world")};
  this.sayName=function(){
    console.log(this.name);}
}
var animal = new Animal();
var cat = new Cat();
Cat.call(animal);
animal.showName.call(cat); // Cat
animal.sayWorld(); //hello world
animal.sayName(); // Cat

3.什么情况下用apply()什么情况下用call()

  在给对象参数的情况下,如果参数的形式是数组的时候,比如apply示例里面传递了参数arguments,这个参数是数组类型,并且在调用Person的时候参数的列表是对应一致的(也就是Person和Student的参数列表前两位是一致的) 就可以采用 apply , 如果我的Person的参数列表是这样的(age,name),而Student的参数列表是(name,age,grade),这样就可以用call来实现了,也就是直接指定参数列表对应值的位置(Person.call(this,age,name,grade));

  学习自:http://www.cnblogs.com/delin/archive/2010/06/17/1759695.html

    http://www.cnblogs.com/KeenLeung/archive/2012/11/19/2778229.html

js中apply()和call()方法的使用的更多相关文章

  1. 原生JS中apply()方法的一个值得注意的用法

    今天在学习vue.js的render时,遇到需要重复构造多个同类型对象的问题,在这里发现原生JS中apply()方法的一个特殊的用法: var ary = Array.apply(null, { &q ...

  2. js中apply方法的使用

    js中apply方法的使用   1.对象的继承,一般的做法是复制:Object.extend prototype.js的实现方式是: Object.extend = function(destinat ...

  3. node.js中的url.parse方法使用说明

    node.js中的url.parse方法使用说明:https://blog.csdn.net/swimming_in_it_/article/details/77439975 版权声明:本文为博主原创 ...

  4. javascript 中 apply(或call)方法的用途----对象的继承

    一直以来,我的理解就是  js中的Function.apply(或者是Function.call)方法是来改变Function 这个函数的执行上下文(excute Context),说白了,就是改变执 ...

  5. JavaScript中apply与call方法

    一.定义 apply:应用某一对象的一个方法,用另一个对象替换当前对象. call:调用一个对象的一个方法,以另一个对象替换当前对象. 二.apply //apply function Person( ...

  6. javascript中apply()和call()方法及区别

    call()和apply()方法 1.方法定义 call方法: 语法:obj.call(thisObj, arg1, arg2, ...); 定义:调用一个对象的一个方法,以另一个对象替换当前对象. ...

  7. prototype.js中Function.prototype.bind方法浅解

    prototype.js中的Function.prototype.bind方法: Function.prototype.bind = function() { var __method = this; ...

  8. js中apply详解

    学习http://www.cnblogs.com/delin/archive/2010/06/17/1759695.html 1.对象的继承,一般的做法是复制:Object.extend protot ...

  9. JS中的对象和方法简单剖析

    众所周知,在js中对象就是精髓,不理解对象就是不理解js. 那么什么事js中的对象呢? 在js中,几乎一切皆对象: Boolean ,String,Number可以是对象(或者说原生数据被认作对象): ...

随机推荐

  1. SQL Server2008从入门到全面精通 SQL数据库视频教程

    第1章 SQL Server 2008入门知识:1.SQL SERVER 2008简介2.数据库概念3.关系数据库4.范式5.E-R模型6.SQL Server 2008体系结构7.安装IIS服务8. ...

  2. 冒泡排序 & 选择排序 & 插入排序 & 希尔排序 JavaScript 实现

    之前用 JavaScript 写过 快速排序 和 归并排序,本文聊聊四个基础排序算法.(本文默认排序结果都是从小到大) 冒泡排序 冒泡排序每次循环结束会将最大的元素 "冒泡" 到最 ...

  3. Winform开发:在ProgressBar显示百分比数字

    如果不使用Label而是直接在进度条上显示文字,可以扩展一个派生类自己画,代码如下: public partial class Form1 : Form { public Form1() { Init ...

  4. 软件工程(FZU2015)赛季得分榜,第八回合

    目录 第一回合 第二回合 第三回合 第四回合 第五回合 第6回合 第7回合 第8回合 第9回合 第10回合 第11回合 积分规则 积分制: 作业为10分制,练习为3分制:alpha30分: 团队项目分 ...

  5. linux终端常用快捷键

    Ctrl + d       删除一个字符,相当于通常的Delete键(命令行若无任何字符,则相当于exit:处理多行标准输入时也表示EOF ) Ctrl + h       退格删除一个字符,相当于 ...

  6. [转]Struts2.3.16.1+Hibernate4.3.4+Spring4.0.2 框架整合

    原文地址:http://blog.csdn.net/ycb1689/article/details/22928519 最新版Struts2+Hibernate+Spring整合 目前为止三大框架最新版 ...

  7. 由Memcached升级到 Couchbase的 Java 客户端的过程记录(三)

    采用之前的源码运行后,我们发现 只有一个配置信息 即servers=127.0.0.1:11211,即 Couchbase Server的服务所在ip 和端口,此时数据直接存在 default 中 根 ...

  8. Linux文件计数

    1.当前目录下的文件数 ls -l |grep "^-"|wc -l 2.当前目录的目录树 ls -l |grep "^d"|wc -l 3.当前目录文件数包含 ...

  9. pair correlation ggpair ggmatrix

    https://zhuanlan.zhihu.com/p/23400450 首发于 R语言数据分析与可视化 关注专栏 登录 写文章     R 语言矩阵散点图 EasyCharts· 15 天前 散点 ...

  10. arguments

    arguments 转数组 通常使用下面的方法来将 arguments 转换成数组: Array.prototype.slice.call(arguments); 还有一个更简短的写法: [].sli ...