js的继承方法小结(prototype、call、apply)(推荐)


Posted in Javascript onApril 17, 2019

js的原型继承 --  prototype

先说下什么是prorotype?

  1. js中,俗话说“一切皆对象”。用new 出来的都是函数对象;否则就是普通对象
  2. 函数对象都有prototype(原型对象);而普通对象则只有__proto__(原型指针)
  3. 函数对象的一个特点:可以实现不同类之间的方法继承
  4. 函数的子类可以共享父类的方法,而父类不能想用子类的方法
eg: (prototype的继承)
 
 //创建父类函数对象  
 function Personal(name, age) {
  this.name = name;   //父类的私有属性
  this.age = age;
  this.house = ['北京', '上海']
 }
 Personal.prototype.run = function() {  //给父类原型动态添加方法
  alert('原型方法:' + this.name + ' is running!');
 }
 var per = new Personal('小白', 24)
 per.run() //打印 --> 原型方法:小白 is running!
 
 //创建子类函数对象
 function Boy() {}
 Boy.prototype = new Personal('小黑', 19) //子类继承父类的所有属性和方法
 Boy.prototype.source = 100      //给子类添加原型属性
 Boy.prototype.printSource = function() { //给子类添加方法
  alert(this.name + '的原型方法printSouce打印成绩为:' + this.source) //小黑的原型方法printSouce打印成绩为:100
 }
 Boy.prototype.run()  //打印 --> 原型方法:小黑 is running!
 var boys = new Boy()
 boys.printSource()
 console.log(boys, '--boys---') //打印 -->19, 小黑, 100 (这里会沿着prototype向上查找到Personal的属性)

以下是关于prototype继承需要注意的点:

1.如果父类中有引用类型的属性:Array,Object等。子类继承了这些属性,并尝试改变的话,会影响到父类的属性。

//创建另外一个实例1:
   var boys1 = new Boy()
   boys1.house.push('深圳')
//打印这两个实例:
   console.log(boys, boys1)

js的继承方法小结(prototype、call、apply)(推荐)

可以看出来,当属性为引用类型时,只要有一个实例的属性做了操作,所有的实例都会受到影响。

2.该方式导致 Boy.prototype.constructor 被重写,它指向的是 Personal 而非 Boy。因此你需要手动将 Boy.prototype.constructor 指回 Boy。

Boy.prototype = new Personal();
Boy.prototype.constructor === Personal; // true

// 重写 Boy.prototype 中的 constructor 属性,指向自己的构造函数 Boy
Boy.prototype.constructor = Boy;

3.因为 Boy.prototype = new Personal(); 重写了 Boy 的原型对象,所以 printSource 放在重写原型对象之前会被覆盖掉,因此给子类添加原型方法必须在替换原型之后(eg是没有被覆盖的)。

function Boy() {}
Boy.prototype = new Personal();

// 给子类添加原型方法必须在替换原型之后
Boy.prototype.printSource = function() {
 console.log('printSource~');
};

4.创建 boys 实例时无法向父类的构造函数传参,也就是无法初始化 source属性。因此:只能创建实例之后再修改父类的属性。

const boys = new Boy();

// 只能创建实例之后再修改父类的属性
boys.source = 100;

apply()、call()方法的继承

了解下apply()、call()方法

1.apply()、call()的用法:

obj.call(thisObj, arg1, arg2, ...);
obj.apply(thisObj, [arg1, arg2, ...]);

obj是父级,thisObj是子级;第二个参数apply可以接收一个数组,而call只能是每项逐个接收。

2.apply和call 本来就是为了扩展函数的作用域而生的,换句话说就是为了改变this的指向存在的。

3.当一个object没有某种方法,但是其他的有,我们可以借助call和apply来用其他对象的方法来做操作,也可以传参数。

//eg:
function Personal(name, sex) {
   this.name = name;
   this.sex = sex;
   this.say = function (){
    alert('姓名:' + this.name + ';性别:' + this.sex)
   }
  }
  const per = new Personal('Allan', '男')
  per.say();
  
//apply()方法实现:
  function Girls(name, sex) {
   Personal.apply(this, [name, sex]);
   //Person.apply(this,arguments); //跟上句一样的效果,arguments 
   //Print.apply(this,arguments); //还可以实现继承多个父类,但是原型 prototype只能继承一个父类!!!切记
  }
  const girls1 = new Girls('Lucy', '女')
  girls1.say();
  
//call()实现:
  function Boy(name, sex) {
   Personal.call(this, name, sex);
  }
  const boys = new Boy('Barry', '男');
  boys.say() //

总结:

  1. prototype可以动态的给对象增加属性和方法。
  2. 可以实现子类继承父类,拥有父类的属性和方法。
  3. call和apply的区别,在于参数的不同。
  4. call和apply,理解为在子类的运行环境中执行父类的方法和属性。
  5. call和apply可以实现一个子类继承多个父类,但是prototype只能有一个父类。

 以上所述是小编给大家介绍的js的继承方法小结详解整合,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!

Javascript 相关文章推荐
JSON 和 JavaScript eval使用说明
Jun 13 Javascript
怎么选择Javascript框架(Javascript Framework)
Nov 22 Javascript
JavaScript生成随机数的4种自定义函数分享
Feb 28 Javascript
谈一谈JS消息机制和事件机制的理解
Apr 14 Javascript
JS正则验证多个邮箱完整实例【邮箱用分号隔开】
Apr 19 Javascript
JS仿QQ好友列表展开、收缩功能(第二篇)
Jul 07 Javascript
JS运动改变单物体透明度的方法分析
Jan 23 Javascript
Vue中使用ElementUI使用第三方图标库iconfont的示例
Oct 11 Javascript
Node.js JSON模块用法实例分析
Jan 04 Javascript
vue实现固定位置显示功能
May 30 Javascript
JavaScript定时器设置、使用与倒计时案例详解
Jul 08 Javascript
vue tab滚动到一定高度,固定在顶部,点击tab切换不同的内容操作
Jul 22 Javascript
详解JavaScript的内存空间、赋值和深浅拷贝
Apr 17 #Javascript
Vue源码探究之虚拟节点的实现
Apr 17 #Javascript
ES6知识点整理之数组解构和字符串解构的应用示例
Apr 17 #Javascript
ES6知识点整理之对象解构赋值应用示例
Apr 17 #Javascript
ES6知识点整理之函数对象参数默认值及其解构应用示例
Apr 17 #Javascript
仿vue-cli搭建属于自己的脚手架的方法步骤
Apr 17 #Javascript
一篇文章,教你学会Vue CLI 插件开发
Apr 17 #Javascript
You might like
PHP5.0对象模型探索之抽象方法和抽象类
2006/09/05 PHP
PHP模板引擎SMARTY
2006/10/09 PHP
PHP中time(),date(),mktime()区别介绍
2013/09/28 PHP
基于jquery的网页SELECT下拉框美化代码
2010/10/28 Javascript
jQuery列表拖动排列具体实现
2013/11/04 Javascript
常用的JS验证和函数汇总
2014/12/23 Javascript
Jquery判断radio、selelct、checkbox是否选中及获取选中值方法总结
2015/04/15 Javascript
浅谈javascript中的闭包
2015/05/13 Javascript
js实现文字闪烁特效的方法
2015/12/17 Javascript
Bootstrap modal 多弹窗之叠加显示不出弹窗问题的解决方案
2017/02/23 Javascript
vue 2.0路由之路由嵌套示例详解
2017/05/08 Javascript
使用jQuery 操作table 完成单元格合并的实例
2017/12/27 jQuery
vue通过路由实现页面刷新的方法
2018/01/25 Javascript
Node.js利用console输出日志文件的方法示例
2018/04/27 Javascript
小程序云开发实现数据库异步操作同步化
2019/05/18 Javascript
如何解决js函数防抖、节流出现的问题
2019/06/17 Javascript
使用Python编写类UNIX系统的命令行工具的教程
2015/04/15 Python
python批量修改图片后缀的方法(png到jpg)
2018/10/25 Python
Python GUI编程学习笔记之tkinter界面布局显示详解
2020/03/30 Python
Django通过设置CORS解决跨域问题
2020/11/26 Python
python中lower函数实现方法及用法讲解
2020/12/23 Python
python des,aes,rsa加解密的实现
2021/01/16 Python
塑料制成的可水洗的编织平底鞋和鞋子:Rothy’s
2018/09/16 全球购物
俄罗斯皮肤健康中心:Pharmacosmetica.ru
2020/02/22 全球购物
在C中是否有模拟继承等面向对象程序设计特性的好方法
2012/05/22 面试题
行政助理的职责
2013/11/14 职场文书
工作失职造成投诉的检讨书范文
2014/10/05 职场文书
护士辞职信怎么写
2015/02/27 职场文书
2015年机关纠风工作总结
2015/05/15 职场文书
围城读书笔记
2015/06/26 职场文书
简短清晨问候语
2015/11/10 职场文书
高中优秀作文(范文)
2019/08/15 职场文书
Nginx配置SSL证书出错解决方案
2021/03/31 Servers
Django中的JWT身份验证的实现
2021/05/07 Python
MySQL如何快速创建800w条测试数据表
2022/03/17 MySQL
Python通过loop.run_in_executor执行同步代码 同步变为异步
2022/04/11 Python