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 相关文章推荐
js onload事件不起作用示例分析
Oct 09 Javascript
javascript实现控制文字大中小显示
Apr 28 Javascript
初识angular框架后的所思所想
Feb 19 Javascript
Avalon中文长字符截取、关键字符隐藏、自定义过滤器
May 18 Javascript
移动端jQuery修正Web页面滑动时div问题的两则实例
May 30 Javascript
js与jquery正则验证电子邮箱、手机号、邮政编码的方法
Jul 04 Javascript
knockoutjs动态加载外部的file作为component中的template数据源的实现方法
Sep 01 Javascript
利用jQuery实现打字机字幕效果实例代码
Sep 02 Javascript
jQuery实现的仿百度,仿谷歌搜索下拉框效果示例
Dec 30 Javascript
详解使用jQuery.i18n.properties实现js国际化
May 04 jQuery
基于jQuery实现无缝轮播与左右点击效果
May 13 jQuery
(开源)微信小程序+mqtt,esp8266温湿度读取
Apr 02 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
PHP开发入门教程之面向对象
2006/12/05 PHP
php中的静态变量的基本用法
2014/03/20 PHP
ThinkPHP使用心得分享-分页类Page的用法
2014/05/15 PHP
PHP中soap的用法实例
2014/10/24 PHP
PHP使用preg_split()分割特殊字符(元字符等)的方法分析
2017/02/04 PHP
PHP使用标准库spl实现的观察者模式示例
2018/08/04 PHP
PHP加MySQL消息队列深入理解
2021/02/27 PHP
jquery easyui滚动条部分设置介绍
2013/09/12 Javascript
javascript 获取网页标题代码实例
2014/01/22 Javascript
JS实现漂亮的窗口拖拽效果(可改变大小、最大化、最小化、关闭)
2015/10/10 Javascript
分享自己用JS做的扫雷小游戏
2016/02/17 Javascript
浅谈jquery.form.js的ajaxSubmit和ajaxForm的使用
2016/09/09 Javascript
js实现点击图片自动提交action的简单方法
2016/10/16 Javascript
bootstrap读书笔记之CSS组件(上)
2016/10/17 Javascript
微信小程序 跳转传参数与传对象详解及实例代码
2017/03/14 Javascript
JavaScript Date对象应用实例分享
2017/10/30 Javascript
jQuery实现模糊查询的方法分析
2018/05/10 jQuery
node中间层实现文件上传功能
2018/06/11 Javascript
6种JavaScript继承方式及优缺点(小结)
2020/02/06 Javascript
实用的 vue tags 创建缓存导航的过程实现
2020/12/03 Vue.js
为python设置socket代理的方法
2015/01/14 Python
python线程、进程和协程详解
2016/07/19 Python
Python Socket传输文件示例
2017/01/16 Python
python3模块smtplib实现发送邮件功能
2018/05/22 Python
numpy给array增加维度np.newaxis的实例
2018/11/01 Python
python使用配置文件过程详解
2019/12/28 Python
基于pytorch的lstm参数使用详解
2020/01/14 Python
从训练好的tensorflow模型中打印训练变量实例
2020/01/20 Python
莫斯科隐形眼镜网上商店:Linzi
2019/07/22 全球购物
房务中心文员岗位职责
2014/04/16 职场文书
说明书范文
2014/05/07 职场文书
离职证明标准格式
2014/09/15 职场文书
2015圣诞节贺卡寄语
2015/03/24 职场文书
微信小程序结合ThinkPHP5授权登陆后获取手机号
2021/11/23 PHP
Java8利用Stream对列表进行去除重复的方法详解
2022/04/14 Java/Android
Java版 单机五子棋
2022/05/04 Java/Android