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 相关文章推荐
在页面上点击任一链接时触发一个事件的代码
Apr 07 Javascript
javascript contains和compareDocumentPosition 方法来确定是否HTML节点间的关系
Feb 04 Javascript
JavaScript 设计模式 安全沙箱模式
Sep 24 Javascript
PHP使用方法重载实现动态创建属性的get和set方法
Nov 17 Javascript
JavaScript中的getTimezoneOffset()方法使用详解
Jun 10 Javascript
JavaScript DOM节点操作方法总结
Aug 23 Javascript
Vue.js常用指令汇总(v-if、v-for等)
Nov 03 Javascript
Bootstrap轮播图的使用和理解4
Dec 14 Javascript
使用Node.js实现简易MVC框架的方法
Aug 07 Javascript
微信小程序实现收藏与取消收藏切换图片功能
Aug 03 Javascript
angular4+百分比进度显示插件用法示例
May 05 Javascript
vuejs+element UI table表格中实现禁用部分复选框的方法
Sep 20 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中实现汉字转区位码应用源码实例解析
2010/06/14 PHP
PHP垃圾回收机制简单说明
2010/07/22 PHP
配置php网页显示各种语法错误
2013/09/23 PHP
彻底删除thinkphp3.1案例blog标签的方法
2014/12/05 PHP
CI(CodeIgniter)框架实现图片上传的方法
2017/03/24 PHP
基于Laravel(5.4版本)的基本增删改查操作方法
2019/10/11 PHP
Javascript实例教程(19) 使用HoTMetal(7)
2006/12/23 Javascript
jQuery 名称冲突的解决方法
2011/04/08 Javascript
可恶的ie8提示缺少id未定义
2014/03/20 Javascript
如何将php数组或者对象传递给javascript
2014/03/20 Javascript
纯JS实现旋转图片3D展示效果
2015/04/12 Javascript
jQuery+Ajax+PHP+Mysql实现分页显示数据实例讲解
2015/09/27 Javascript
AngularJS Module方法详解
2015/12/08 Javascript
js实现四舍五入完全保留两位小数的方法
2016/08/02 Javascript
简单实现node.js图片上传
2016/12/18 Javascript
JavaScript对象封装的简单实现方法(3种方法)
2017/01/03 Javascript
jQuery EasyUI tree增加搜索功能的实现方法
2017/04/27 jQuery
浅谈Angular4实现热加载开发旅程
2017/09/08 Javascript
基于Bootstrap表单验证功能
2017/11/17 Javascript
vuex页面刷新后数据丢失的方法
2019/01/17 Javascript
JavaScript正则表达式验证登录实例
2020/03/18 Javascript
python使用标准库根据进程名如何获取进程的pid详解
2017/10/31 Python
tensorflow学习笔记之简单的神经网络训练和测试
2018/04/15 Python
使用Python做定时任务及时了解互联网动态
2019/05/15 Python
Python实现CNN的多通道输入实例
2020/01/17 Python
Python unittest装饰器实现原理及代码
2020/09/08 Python
TUMI马来西亚官方网站:国际领先的高品质商旅箱包品牌
2018/04/26 全球购物
全球领先的在线cosplay服装商店:RoleCosplay
2020/01/18 全球购物
施华洛世奇中国官网:SWAROVSKI中国
2020/06/16 全球购物
应聘护理专业毕业自荐书范文
2014/02/12 职场文书
2014学雷锋活动心得体会
2014/03/10 职场文书
我的长征观后感
2015/06/09 职场文书
Java实战之用Swing实现通讯录管理系统
2021/06/13 Java/Android
Python类方法总结讲解
2021/07/26 Python
Python面试不修改数组找出重复的数字
2022/05/20 Python
MySQL控制流函数(-if ,elseif,else,case...when)
2022/07/07 MySQL