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 Array扩展实现代码
Oct 14 Javascript
JavaScript高级程序设计 客户端存储学习笔记
Sep 10 Javascript
JQuery的AJAX实现文件下载的小例子
May 15 Javascript
Jquery右下角抖动、浮动 实例代码(兼容ie6、FF)
Aug 15 Javascript
javascript ajax的5种状态介绍
Aug 18 Javascript
jQuery支持动态参数将函数绑定到事件上的方法
Mar 17 Javascript
JavaScript 数组some()和filter()的用法及区别
May 20 Javascript
angularJS之$http:与服务器交互示例
Mar 17 Javascript
JavaScript正则表达式和级联效果
Sep 14 Javascript
vue通过点击事件读取音频文件的方法
May 30 Javascript
浅谈微信小程序flex布局基础
Sep 10 Javascript
vue多层嵌套路由实例分析
Mar 19 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中常用的转义函数
2014/02/28 PHP
php实现概率性随机抽奖代码
2016/01/02 PHP
PHP编写学校网站上新生注册登陆程序的实例分享
2016/03/21 PHP
php设计模式之中介者模式分析【星际争霸游戏案例】
2020/03/23 PHP
用roll.js实现的图片自动滚动+鼠标触动的特效
2007/03/18 Javascript
javascript 去字符串空格终极版(支持utf8)
2009/11/14 Javascript
多浏览器兼容的获取元素和鼠标的位置的js代码
2009/12/15 Javascript
JS按字节截取字符长度实例
2013/11/20 Javascript
JQuery实现绚丽的横向下拉菜单
2013/12/19 Javascript
jQuery使用fadeout实现元素渐隐效果的方法
2015/03/27 Javascript
javascript每日必学之封装
2016/02/23 Javascript
各种选择框jQuery的选中方法(实例讲解)
2017/06/27 jQuery
使用Node.js实现简易MVC框架的方法
2017/08/07 Javascript
laravel5.4+vue+element简单搭建的示例代码
2017/08/29 Javascript
JS实现数组简单去重及数组根据对象中的元素去重操作示例
2018/01/05 Javascript
javascript填充默认头像方法
2018/02/22 Javascript
vue服务端渲染添加缓存的方法
2018/09/18 Javascript
react的滑动图片验证码组件的示例代码
2019/02/27 Javascript
js继承的这6种方式!(上)
2019/04/23 Javascript
vue 使用鼠标滚动加载数据的例子
2019/10/31 Javascript
原生JS实现拖拽功能
2020/12/16 Javascript
[57:50]DOTA2上海特级锦标赛主赛事日 - 4 胜者组决赛Secret VS Liquid第二局
2016/03/05 DOTA
[43:03]LGD vs Newbee 2019国际邀请赛小组赛 BO2 第一场 8.16
2019/08/19 DOTA
Python反射用法实例简析
2017/12/22 Python
用python求一个数组的和与平均值的实现方法
2019/06/29 Python
Python监控服务器实用工具psutil使用解析
2019/12/19 Python
简单了解Django ORM常用字段类型及参数配置
2020/01/07 Python
使用Tensorflow将自己的数据分割成batch训练实例
2020/01/20 Python
Tensorflow中的降维函数tf.reduce_*使用总结
2020/04/20 Python
python numpy实现rolling滚动案例
2020/06/08 Python
基于Python爬取京东双十一商品价格曲线
2020/10/23 Python
css3如何绘制一个圆圆的loading转圈动画
2018/01/09 HTML / CSS
开会迟到检讨书
2014/02/03 职场文书
高中班主任心得体会
2016/01/07 职场文书
原生JS中应该禁止出现的写法
2021/05/05 Javascript
缓存替换策略及应用(以Redis、InnoDB为例)
2021/07/25 Redis