JS中call和apply函数用法实例分析


Posted in Javascript onJune 20, 2018

本文实例讲述了JS中call和apply函数用法。分享给大家供大家参考,具体如下:

call 函数

语法

obj.call(thisObj,arg[,arg2[,arg3[,...agr]]]);

简介

thisObj继承obj的属性和方法(obj原型链上的属性和方法不能被继承),后面的参数会当成obj的参数安装顺序传递进去。

示例

function animal(type,nickname){
    this.type = type;
    this.nickname = nickname;
    this.sayHello = function(){
      return 'hello';
    }
}
function cat(name,type,nickname){
    this.name = name;
    //cat继承animal
    animal.call(this,type,nickname);
}
console.log(new cat('wsscat','cut','tom'));
/*
cat {
 name: 'wsscat',
 type: 'cut',
 nickname: 'tom',
 sayHello: [Function] }
*/

apply 函数

语法

obj.apply(this[,argArray]);

简介

apply和call的作用差不多,都可以用来继承,区别在与apply只有两个参数,第二个参数必须是数组或者arguments对象。否则会报TypeError错误。如果继承的对象obj有多个参数,则会吧argArray的参数依次对应obj的每个参数。

示例

function animal(type,nickname){
    this.type = type;
    this.nickname = nickname;
    this.syaHello = function(){
      return 'hello';
    }
}
function cat(name,type,nickname){
    this.name = name;
    animal.apply(this,arguments);
}
console.log(new cat('wsscat','cut','tom'));
/*
cat {
 name: 'wsscat',
 type: 'wsscat',
 nickname: 'cut',
 syaHello: [Function] }
*/

总结

callapply功能是相同的

相同点在于都是用于对象的继承,第一个参数都是thisObj.

不同点在于call可以有多个参数,从第二个参数开始往后的参数会依次传给被继承的对象做参数。apply只有两个参数,第二个参数必须是数组类型或者arguments对象类型,而且他会把数组中的元素依次传递给被继承的对象做参数。

通过以上几点,我们可以得到如果被继承的对象只有一个参数的可以使用call,如果被继承的对象有多个参数的,建议使用apply.

补充

js中可以实现多继承,只需要调用多次call或apply即可。如:

function animal(type,nickname){
    this.type = type;
    this.nickname = nickname;
    this.syaHello = function(){
      return 'hello';
    }
}
function wscat(name,age){
    this.name = name;
    this.age = age;
    this.sayMe = function(){
      return 'my name:' + this.name + ', age:' + this.age;
    }
}
function cat(name,age,type,nickname){
    //第一种使用call
    animal.call(this,type,nickname);
    wscat.call(this,name,age);
    //第二种使用apply
    //animal.apply(this,[type,nickname]);
    //wscat.apply(this,[name,age]);
}
console.log(new cat('wscat',2,'cat','tom');
/*
cat {
 type: 'cat',
 nickname: 'tom',
 syaHello: [Function],
 name: 'wscat',
 age: 2,
 sayMe: [Function] }
*/

继承的优化

如果构造函数this绑定了太多的属性(比如一些共用的函数),示例化后就会照成浪费(因为this里的属性和方法实例化后会复制一份给新对象,多个对象之间的属性和方法互不干涉,对于一些可以共用的方法来就会造成浪费)

所以我们一般把共用的函数都放在原型链(prototype)上。但是使用call和apply无法继承原型链上的属性和方法。

因此我们可以使用混合的而写法,使用原型链和(applycall)组合的方式进行继承。

让子的原型链指向父的示例(父的实例化对象)。如:

cat.prototype = new animal();

让父的属性创建在子的this上。如:

animal.call(this[,arg]);
//animal.apply(this[,argArray]);

具体代码如下:

function animal(type,nickname){
    this.type = type;
    this.nickname = nickname;
}
animal.prototype.sayHello = function(){
    return 'hello';
}
function wscat(name,age){
    this.name = name;
    this.age = age;
} 
//这里是关键,原型链只能单继承,
//不能同时继承多个原型链,所以要一级一级来。
wscat.prototype = new animal();
wscat.prototype.sayMe = function(){
    return 'my name:' + this.name + ', age:' + this.age;
}
function cat(name,age,type,nickname){
    animal.call(this,type,nickname);
    wscat.call(this,name,age);
}
cat.prototype = new wscat();
var obj = new cat('wscat',10,'cat','tom');
console.log(obj);
//animal { type: 'cat', nickname: 'tom', name: 'wscat', age: 10 }
console.log(obj.sayHello());//hello
console.log(obj.sayMe());
/*
    my name:wscat, age:10
*/

希望本文所述对大家JavaScript程序设计有所帮助。

Javascript 相关文章推荐
jq选项卡鼠标延迟的插件实例
May 13 Javascript
纯js分页代码(简洁实用)
Nov 05 Javascript
Jquery焦点图实例代码
Nov 25 Javascript
jquery的ajax提交form表单的两种方法小结(推荐)
May 25 Javascript
JavaScript实现时间倒计时跳转(推荐)
Jun 28 Javascript
微信小程序 navigation API实例详解
Oct 02 Javascript
微信小程序 利用css实现遮罩效果实例详解
Jan 21 Javascript
JavaScript和JQuery获取DIV值的方法示例
Mar 07 Javascript
[原创]jQuery实现合并/追加数组并去除重复项的方法
Apr 11 jQuery
对layui中表单元素的使用详解
Aug 15 Javascript
13 个npm 快速开发技巧(推荐)
Jul 04 Javascript
JavaScript获取某一天所在的星期
Sep 05 Javascript
微信小程序模拟cookie的实现
Jun 20 #Javascript
JS伪继承prototype实现方法示例
Jun 20 #Javascript
通过jquery.cookie.js实现记住用户名、密码登录功能
Jun 20 #jQuery
Vue.JS实现垂直方向展开、收缩不定高度模块的JS组件
Jun 19 #Javascript
Vue兼容ie9的问题全面解决方案
Jun 19 #Javascript
详解Vue-cli中的静态资源管理(src/assets和static/的区别)
Jun 19 #Javascript
vue-cli2.x项目优化之引入本地静态库文件的方法
Jun 19 #Javascript
You might like
PHP安装攻略:常见问题解答(三)
2006/10/09 PHP
FleaPHP的安全设置方法
2008/09/15 PHP
PHP 的异常处理、错误的抛出及回调函数等面向对象的错误处理方法
2012/12/07 PHP
php 地区分类排序算法
2013/07/01 PHP
php实现搜索一维数组元素并删除二维数组对应元素的方法
2015/07/06 PHP
PHP实现获取第一个中文首字母并进行排序的方法
2017/05/09 PHP
showModalDialog 和 showModelessDialog
2007/01/22 Javascript
JQuery 将元素显示在屏幕的中央的代码
2010/02/27 Javascript
JS鼠标滚动分页效果示例
2017/07/05 Javascript
详解vue-cli 本地开发mock数据使用方法
2018/05/29 Javascript
Vue slot用法(小结)
2018/10/22 Javascript
Vue实现简易翻页效果源码分享
2018/11/08 Javascript
详解vue中this.$emit()的返回值是什么
2019/04/07 Javascript
如何从头实现一个node.js的koa框架
2019/06/17 Javascript
jquery.pager.js实现分页效果
2019/07/29 jQuery
深入浅析vue中cross-env的使用
2019/09/12 Javascript
Django实现的自定义访问日志模块示例
2017/06/23 Python
Python Opencv任意形状目标检测并绘制框图
2019/07/23 Python
python plotly画柱状图代码实例
2019/12/13 Python
Python3自定义http/https请求拦截mitmproxy脚本实例
2020/05/11 Python
python json.dumps() json.dump()的区别详解
2020/07/14 Python
法国珠宝店:CLEOR
2017/01/29 全球购物
大学教师年终总结的自我评价
2013/10/29 职场文书
给排水工程师岗位职责
2013/11/21 职场文书
商务专员岗位职责
2013/11/23 职场文书
党员违纪检讨书
2014/02/18 职场文书
新农村建设典型材料
2014/05/31 职场文书
家长会标语
2014/06/24 职场文书
幼儿园母亲节活动总结
2015/02/10 职场文书
2015年技术工作总结范文
2015/04/20 职场文书
2015社区个人工作总结范文
2015/05/13 职场文书
小数乘法教学反思
2016/02/22 职场文书
数据库连接池
2021/04/06 MySQL
健身房被搭讪?用python写了个小米计时器助人为乐
2021/06/08 Python
OpenStack虚拟机快照和增量备份实现方法
2022/04/04 Servers
nginx搭建NFS网络文件系统
2022/04/14 Servers