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 相关文章推荐
JavaScript 常见对象类创建代码与优缺点分析
Dec 07 Javascript
JQueryiframe页面操作父页面中的元素与方法(实例讲解)
Nov 19 Javascript
js弹出确认是否删除对话框
Mar 27 Javascript
JQuery中使用Ajax赋值给全局变量失败异常的解决方法
Aug 18 Javascript
js实时获取并显示当前时间的方法
Jul 31 Javascript
全面介绍javascript实用技巧及单竖杠
Jul 18 Javascript
jQuery实现花式轮播之圣诞节礼物传送效果
Dec 25 Javascript
jQuery实现点击下拉框中的值累加到文本框中的方法示例
Oct 28 jQuery
用node撸一个监测复联4开售短信提醒的实现代码
Apr 10 Javascript
解决VUE-Router 同一页面第二次进入不刷新的问题
Jul 22 Javascript
vue-列表下详情的展开与折叠案例
Jul 28 Javascript
jquery实现鼠标悬浮弹出气泡提示框
Dec 23 jQuery
详解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
php 文章采集正则代码
2009/12/28 PHP
php中autoload的用法总结
2013/11/08 PHP
使用CodeIgniter的类库做图片上传
2014/06/12 PHP
PHP连接sftp并下载文件的方法教程
2018/08/26 PHP
关于PHP求解三数之和问题详析
2020/11/09 PHP
自适应高度框架 ----属个人收藏内容
2007/01/22 Javascript
List Information About the Binary Files Used by an Application
2007/06/18 Javascript
javascript下过滤数组重复值的代码
2007/09/10 Javascript
用javascript获取当页面上鼠标光标位置和触发事件的对象的代码
2009/12/09 Javascript
DD_belatedPNG,IE6下PNG透明解决方案(国外)
2010/12/06 Javascript
JS多物体 任意值 链式 缓冲运动
2012/08/10 Javascript
jQuery实现id模糊查询的小例子
2013/03/19 Javascript
JS实现霓虹灯文字效果的方法
2015/08/06 Javascript
js将table的每个td的内容自动赋值给其title属性的方法
2016/10/13 Javascript
js实现音频控制进度条功能
2017/04/01 Javascript
详解vue-cli + webpack 多页面实例配置优化方法
2017/07/13 Javascript
vue里面父组件修改子组件样式的方法
2018/02/03 Javascript
详解Vue SSR( Vue2 + Koa2 + Webpack4)配置指南
2018/11/13 Javascript
[40:17]2018DOTA2亚洲邀请赛 4.5 淘汰赛 LGD vs Liquid 第一场
2018/04/06 DOTA
python二叉树遍历的实现方法
2013/11/21 Python
Python输入二维数组方法
2018/04/13 Python
Django 限制用户访问频率的中间件的实现
2018/08/23 Python
Python子类继承父类构造函数详解
2019/02/19 Python
python实现udp聊天窗口
2020/03/31 Python
python主要用于哪些方向
2020/07/05 Python
详解KMP算法以及python如何实现
2020/09/18 Python
定制iPhone和Macbook保护壳:Slick Case
2018/11/21 全球购物
前台接待的工作职责
2013/11/21 职场文书
优秀实习自我鉴定
2013/12/04 职场文书
环保志愿者活动方案
2014/08/14 职场文书
小学庆六一活动总结
2014/08/28 职场文书
就业证明函
2015/06/17 职场文书
写给同事的离职感言
2015/08/04 职场文书
2016年万圣节活动个人总结
2016/04/05 职场文书
python自动化操作之动态验证码、滑动验证码的降噪和识别
2021/08/30 Python
JS实现九宫格拼图游戏
2022/06/28 Javascript