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 实现的点击复制代码
Mar 24 Javascript
几行代码轻松搞定jquery实现flash8类似的连接效果
May 03 Javascript
JS+ACTIVEX实现网页选择本地目录路径对话框
Mar 18 Javascript
jQuery复制表单元素附源码分享效果演示
Sep 30 Javascript
AngularJs 弹出模态框(model)
Apr 07 Javascript
javascript简单实现跟随滚动条漂浮的返回顶部按钮效果
Aug 19 Javascript
JQuery.validationEngine表单验证插件(推荐)
Dec 10 Javascript
微信小程序中实现一对多发消息详解及实例代码
Feb 14 Javascript
基于JavaScript实现五子棋游戏
Aug 26 Javascript
VSCode配置react开发环境的步骤
Dec 27 Javascript
vue项目中运用webpack动态配置打包多种环境域名的方法
Jun 24 Javascript
vue tab切换,解决echartst图表宽度只有100px的问题
Jul 19 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
删除无限级目录与文件代码共享
2006/07/12 PHP
php 数组排序 array_multisort与uasort的区别
2011/03/24 PHP
Yii视图CGridView实现操作按钮定义地址示例
2016/07/14 PHP
使用一个for循环将N*N的二维数组的所有值置1实现方法
2017/05/29 PHP
laravel 实现根据字段不同值做不同查询
2019/10/23 PHP
javascript基于jQuery的表格悬停变色/恢复,表格点击变色/恢复,点击行选Checkbox
2008/08/05 Javascript
JQuery 确定css方框模型(盒模型Box Model)
2010/01/22 Javascript
js写的评论分页(还不错)
2013/12/23 Javascript
判断一个对象是否为jquery对象的方法
2014/03/12 Javascript
Js+Jq获取URL参数的集中方法示例代码
2014/05/20 Javascript
jquery中one()方法的用法实例
2015/01/16 Javascript
js实现屏幕自适应局部代码分享
2015/01/30 Javascript
javascript 继承学习心得总结
2016/03/17 Javascript
浅析C/C++,Java,PHP,JavaScript,Json数组、对象赋值时最后一个元素后面是否可以带逗号
2016/03/22 Javascript
JS+CSS3实现超炫的散列画廊特效
2016/07/16 Javascript
jQuery中each和js中forEach的区别分析
2019/02/27 jQuery
深入解析Python编程中super关键字的用法
2016/06/24 Python
python中安装模块包版本冲突问题的解决
2017/05/02 Python
numpy判断数值类型、过滤出数值型数据的方法
2018/06/09 Python
浅谈Python2、Python3相对路径、绝对路径导入方法
2018/06/22 Python
Python 中使用 PyMySQL模块操作数据库的方法
2019/11/10 Python
tensorflow使用range_input_producer多线程读取数据实例
2020/01/20 Python
解决jupyter notebook显示不全出现框框或者乱码问题
2020/04/09 Python
利用HTML5 Canvas制作一个简单的打飞机游戏
2015/05/11 HTML / CSS
应届生学校辅导员求职信
2013/11/07 职场文书
八年级物理教学反思
2014/01/19 职场文书
2014年党务公开实施方案
2014/02/27 职场文书
加强作风建设演讲稿
2014/10/24 职场文书
被告代理词范文
2015/05/25 职场文书
生死牛玉儒观后感
2015/06/11 职场文书
幼儿园开学温馨提示
2015/07/15 职场文书
2015年度个人工作总结报告
2015/10/24 职场文书
《秋天的怀念》教学反思
2016/02/17 职场文书
2016大学先进团支部事迹材料
2016/03/01 职场文书
创业计划书之干洗店
2019/09/10 职场文书
阿里云日志过滤器配置日志服务
2022/04/09 Servers