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实现的图片马赛克后显示并切换加文字功能
Apr 21 Javascript
javascript下查找父节点的简单方法
Aug 13 Javascript
javascript自执行函数之伪命名空间封装法
Dec 25 Javascript
JS获取select-option-text_value的方法
Dec 26 Javascript
jquery 判断滚动条到达了底部和顶端的方法
Apr 02 Javascript
JavaScript实现表格快速变色效果代码
Aug 19 Javascript
微信小程序 form组件详解及简单实例
Jan 10 Javascript
浅谈angular2的http请求返回结果的subcribe注意事项
Mar 01 Javascript
前端自动化开发之Node.js的环境搭建教程
Apr 01 Javascript
Bootstrap Table使用整理(二)
Jun 09 Javascript
vue router导航守卫(router.beforeEach())的使用详解
Apr 19 Javascript
基于Element的组件改造的树形选择器(树形下拉框)
Feb 27 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
DC漫画《蝙蝠侠和猫女》图透 猫女怀孕老爷当爹
2020/04/09 欧美动漫
PHP设计模式 注册表模式(多个类的注册)
2012/02/05 PHP
php实现读取手机客户端浏览器的类
2015/01/09 PHP
symfony表单与页面实现技巧
2015/01/26 PHP
PHP中static关键字以及与self关键字的区别
2015/07/01 PHP
Laravel中为什么不使用blpop取队列详析
2018/08/01 PHP
使用户点击后退按钮使效三行代码
2007/07/07 Javascript
jquery 模拟雅虎首页的点击对话框效果
2010/04/11 Javascript
JavaScript之HTMLCollection接口代码
2011/04/27 Javascript
JavaScript中的object转换函数toString()与valueOf()介绍
2014/12/31 Javascript
jquery制作 随机弹跳的小球特效
2015/02/01 Javascript
工作中比较实用的JavaScript验证和数据处理的干货(经典)
2016/08/03 Javascript
Bootstrap Search Suggest使用例子
2016/12/21 Javascript
BootStrap select2 动态改变值的方法
2017/02/10 Javascript
JavaScript使用原型和原型链实现对象继承的方法详解
2017/04/05 Javascript
前端构建工具之gulp的语法教程
2017/06/12 Javascript
javaScript canvas实现(画笔大小 颜色 橡皮的实例)
2017/11/28 Javascript
使用Angular CLI生成 Angular 5项目教程详解
2018/03/18 Javascript
小程序瀑布流组件实现翻页与图片懒加载
2020/05/19 Javascript
跟老齐学Python之编写类之四再论继承
2014/10/11 Python
django echarts饼图数据动态加载的实例
2019/08/12 Python
如何使用Python多线程测试并发漏洞
2019/12/18 Python
python集合删除多种方法详解
2020/02/10 Python
CSS3使用transition实现的鼠标悬停淡入淡出
2015/01/09 HTML / CSS
美国内衣第一品牌:Hanes(恒适)
2016/07/29 全球购物
JINS眼镜官方网站:日本最大的眼镜邮购
2016/10/14 全球购物
健康监测猫砂:Pretty Litter
2017/05/25 全球购物
澳大利亚制造的蜡烛和扩散器:Glasshouse Fragrances
2018/05/20 全球购物
如何设置Java的运行环境
2013/04/05 面试题
说一下mysql, oracle等常见数据库的分页实现方案
2012/09/29 面试题
保密普查工作实施方案
2014/02/25 职场文书
《哪吒闹海》教学反思
2014/02/28 职场文书
公司承诺书怎么写
2014/05/24 职场文书
营运督导岗位职责
2015/04/10 职场文书
校园广播站开场白
2015/06/01 职场文书
慰问信(范文3篇)
2019/10/23 职场文书