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 相关文章推荐
ie下动态加态js文件的方法
Sep 13 Javascript
Extjs中使用extend(js继承) 的代码
Mar 15 Javascript
jquery获取多个checkbox的值异步提交给php
Jul 07 Javascript
原生js实现旋转木马轮播图效果
Feb 27 Javascript
easyui datagrid 表格中操作栏 按钮图标不显示的解决方法
Jul 27 Javascript
详解Angular5 路由传参的3种方法
Apr 28 Javascript
深入理解Vue Computed计算属性原理
May 29 Javascript
vue2.0 中使用transition实现动画效果使用心得
Aug 13 Javascript
vue3.0 CLI - 2.2 - 组件 home.vue 的初步改造
Sep 14 Javascript
egg.js的基本使用和调用数据库的方法示例
May 18 Javascript
Angular中innerHTML标签的样式不起作用的原因解析
Jun 18 Javascript
JavaScript 闭包的使用场景
Sep 17 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多个版本的分析解释
2011/07/21 PHP
PHP 杂谈《重构-改善既有代码的设计》之三 重新组织数据
2012/04/09 PHP
php集成环境xampp中apache无法启动问题解决方案
2014/11/18 PHP
php递归删除目录与文件的方法
2015/01/30 PHP
php+html5实现无刷新图片上传教程
2016/01/22 PHP
php array_walk_recursive 使用自定的函数处理数组中的每一个元素
2016/11/16 PHP
ExtJS 2.0 实用简明教程之布局概述
2009/04/29 Javascript
Javascript UrlDecode函数代码
2010/01/09 Javascript
jquery 简单的进度条实现代码
2010/03/11 Javascript
jquery实现table鼠标经过变色代码
2013/09/25 Javascript
javascript圆盘抽奖程序实现原理和完整代码例子
2014/06/03 Javascript
自己动手制作基于jQuery的Web页面加载进度条插件
2016/06/03 Javascript
JS针对Array的各种操作汇总
2016/11/29 Javascript
AngularJS双向绑定和依赖反转实例详解
2017/04/15 Javascript
BootStrap 动态表单效果
2017/06/02 Javascript
JavaScript实现焦点进入文本框内关闭输入法的核心代码
2017/09/20 Javascript
详解vue-cli官方脚手架配置
2018/07/20 Javascript
JS如何获取地址栏的参数实例讲解
2018/10/06 Javascript
Vue动画事件详解及过渡动画实例
2019/02/09 Javascript
详解vue.js移动端配置flexible.js及注意事项
2019/04/10 Javascript
Python(Tornado)模拟登录小米抢手机
2013/11/12 Python
Python使用代理抓取网站图片(多线程)
2014/03/14 Python
python使用正则表达式的search()函数实现指定位置搜索功能
2017/11/10 Python
python读取txt文件中特定位置字符的方法
2018/12/24 Python
Tensorflow训练MNIST手写数字识别模型
2020/02/13 Python
深入浅析Python 函数注解与匿名函数
2020/02/24 Python
Python3 利用face_recognition实现人脸识别的方法
2020/03/13 Python
python数据库操作mysql:pymysql、sqlalchemy常见用法详解
2020/03/30 Python
CSS3制作hover下划线动画
2017/03/27 HTML / CSS
HTML5如何实现元素拖拽
2016/03/11 HTML / CSS
渔夫的故事教学反思
2014/02/14 职场文书
领导党性分析材料
2014/02/15 职场文书
教师年度考核自我评鉴
2015/08/11 职场文书
Idea连接MySQL数据库出现中文乱码的问题
2021/04/14 MySQL
Vue过滤器(filter)实现及应用场景详解
2021/06/15 Vue.js
不负正版帝国之名 《重返帝国》引领SLG手游制作新的标杆
2022/04/07 其他游戏