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 相关文章推荐
高性能JavaScript循环语句和条件语句
Jan 20 Javascript
JavaScript面向对象程序设计教程
Mar 29 Javascript
Angular2 PrimeNG分页模块学习
Jan 14 Javascript
微信小程序page的生命周期和音频播放及监听实例详解
Apr 07 Javascript
JS排序之快速排序详解
Apr 08 Javascript
浅谈KOA2 Restful方式路由初探
Mar 14 Javascript
vue实现百度搜索功能
Dec 28 Javascript
vuex + keep-alive实现tab标签页面缓存功能
Oct 17 Javascript
解决vuex数据异步造成初始化的时候没值报错问题
Nov 13 Javascript
JS制作简易计算器的实例代码
Jul 04 Javascript
vue自动添加浏览器兼容前后缀操作
Aug 13 Javascript
原生js实现表格翻页和跳转
Sep 29 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程序61条面向对象分析设计的经验小结
2008/11/12 PHP
php empty函数判断mysql表单是否为空
2010/04/12 PHP
用PHP读取和编写XML DOM的实现代码
2011/02/03 PHP
header中Content-Disposition的作用与使用方法
2012/06/13 PHP
getimagesize获取图片尺寸实例
2014/11/15 PHP
详解WordPress中用于更新和获取用户选项数据的PHP函数
2016/03/08 PHP
最新优化收藏到网摘代码(digg,diigo)
2007/02/07 Javascript
关于B/S判断浏览器断开的问题讨论
2008/10/29 Javascript
alert中断settimeout计时功能
2013/07/26 Javascript
javascript框架设计之框架分类及主要功能
2015/06/23 Javascript
js实现上传图片及时预览
2016/05/07 Javascript
JavaScript实现页面无操作倒计时退出
2016/10/22 Javascript
JS实现的五级联动菜单效果完整实例
2017/02/23 Javascript
详解利用jsx写vue组件的方法示例
2017/07/17 Javascript
小程序数据通信方法大全(推荐)
2019/04/15 Javascript
原生JS实现烟花效果
2020/03/10 Javascript
详解Node.JS模块 process
2020/08/31 Javascript
JavaScript实现前端倒计时效果
2021/02/09 Javascript
[10:53]2018DOTA2国际邀请赛寻真——EG
2018/08/11 DOTA
python笔记(2)
2012/10/24 Python
Python logging模块学习笔记
2014/05/24 Python
编写Python爬虫抓取豆瓣电影TOP100及用户头像的方法
2016/01/20 Python
Python判断文本中消息重复次数的方法
2016/04/27 Python
Python装饰器知识点补充
2018/05/28 Python
Tensorflow使用tfrecord输入数据格式
2018/06/19 Python
通过cmd进入python的实例操作
2019/06/26 Python
Django 大文件下载实现过程解析
2019/08/01 Python
阿巴庭院:Abba Patio
2019/06/18 全球购物
韩语专业本科生求职信
2013/10/01 职场文书
大专毕业生自我鉴定
2013/11/21 职场文书
优秀导游先进事迹材料
2014/01/25 职场文书
文明餐桌活动方案
2014/02/11 职场文书
幼师小班个人总结
2015/02/12 职场文书
财务会计个人原因辞职信
2019/06/21 职场文书
MySQL通过binlog恢复数据
2021/05/27 MySQL
vue 数字翻牌器动态加载数据
2022/04/20 Vue.js