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 Tab 导航插件 (23个)
Jun 11 Javascript
js 兼容多浏览器的回车和鼠标焦点事件代码(IE6/7/8,firefox,chrome)
Apr 14 Javascript
js动态添加onload、onresize、onscroll事件(另类方法)
Dec 26 Javascript
js函数名与form表单元素同名冲突的问题
Mar 07 Javascript
javascript鼠标右键菜单自定义效果
Dec 08 Javascript
JQuery fileupload插件实现文件上传功能
Mar 18 Javascript
微信小程序 PHP生成带参数二维码
Feb 21 Javascript
XMLHttpRequest对象_Ajax异步请求重点(推荐)
Sep 28 Javascript
jQuery解析json格式数据示例
Sep 01 jQuery
VUE搭建手机商城心得和遇到的坑
Feb 21 Javascript
Javascript之高级数组API的使用实例
Mar 08 Javascript
微信小程序实现吸顶效果
Jan 08 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
安装ImageMagick出现error while loading shared libraries的解决方法
2014/09/23 PHP
PHP图片自动裁切应付不同尺寸的显示
2014/10/16 PHP
php实现singleton()单例模式实例
2014/11/06 PHP
PHP扩展开发教程(总结)
2015/11/04 PHP
WordPress中创建用户角色的相关PHP函数使用详解
2015/12/25 PHP
用jQuery技术实现Tab页界面之二
2009/09/21 Javascript
Jquery 1.42 checkbox 全选和反选代码
2010/03/27 Javascript
Android中资源文件(非代码部分)的使用概览
2012/12/18 Javascript
JS在TextArea光标位置插入文字并实现移动光标到文字末尾
2013/06/21 Javascript
html文本框提示效果的示例代码
2014/06/28 Javascript
Node.js实现的简易网页抓取功能示例
2014/12/05 Javascript
10分钟掌握XML、JSON及其解析
2020/12/06 Javascript
JavaScript常见的五种数组去重的方式
2016/12/15 Javascript
细说webpack源码之compile流程-rules参数处理技巧(2)
2017/12/26 Javascript
Vue中div contenteditable 的光标定位方法
2018/08/25 Javascript
微信小程序 image组件遇到的问题
2019/05/28 Javascript
对vue中的事件穿透与禁止穿透实例详解
2019/10/28 Javascript
微信小程序跨页面传递data数据方法解析
2019/12/13 Javascript
js点击事件的执行过程实例分析【冒泡与捕获】
2020/04/11 Javascript
vue使用element-ui实现表单验证
2020/12/13 Vue.js
[04:02]2014DOTA2国际邀请赛 BBC每日综述中国战队将再度登顶
2014/07/21 DOTA
python3 与python2 异常处理的区别与联系
2016/06/19 Python
Python即时网络爬虫项目启动说明详解
2018/02/23 Python
Python3.遍历某文件夹提取特定文件名的实例
2018/04/26 Python
在Django的View中使用asyncio的方法
2019/07/12 Python
python实时检测键盘输入函数的示例
2019/07/17 Python
Python使用Slider组件实现调整曲线参数功能示例
2019/09/06 Python
Wedgwood美国官网:英国骨瓷,精美礼品及家居装饰
2018/02/17 全球购物
数据库方面面试题
2012/04/22 面试题
Java程序员面试90题
2013/10/19 面试题
大学生创业感言
2014/01/25 职场文书
研究生就业推荐表导师评语
2014/12/31 职场文书
学校党支部公开承诺书
2015/04/30 职场文书
机关单位保密工作责任书
2015/05/11 职场文书
一篇文章了解正则表达式的替换技巧
2022/02/24 Javascript
Java 死锁解决方案
2022/05/11 Java/Android