JavaScript 继承父类方法的正确姿势

不想看前期的介绍可以直接划到最下面看总结和正确姿势,跳过原因的讲解。

初学 js ,总是喜欢把方法直接定义在对象内部,类似于 Java 那样。

下面定义一个简单 js 对象。

function Person() {var locVal = '冲冲冲';this.info = function () {return locVal;}
}
var p = new Person();
var val = p.info();
alert(val);

执行结果:

但是这样定义会产生问题,生成闭包,而且当你定义多个对象时重复调用 info 方法时,会重复生成 info 函数,就会造成系统内存泄漏,从而引起性能下降。

具体有关闭包的有关内容可以参考这篇博客:

https://blog.csdn.net/weixin_44588495/article/details/98113371

那么我们要怎么解决这个问题呢?

我们可以通过 js 提供的 prototype 属性来解决这个问题。

function Person(name,age) {this.name=name;this.age=age;this.info = function () {document.write("姓名:" + this.name + "<br />");document.write("年龄:" + this.age + "<br />");}
}
var p1 = new Person('zkm',20);
p1.info();
Person.prototype.walk = function () {document.write(this.name + "正在慢慢溜达...<br/>");
}
document.write('<hr/>');
var p2 = new Person('ccc',30);
p2.info();
document.write('<hr/>');
p2.walk();
p1.walk();

执行结果:

在这里我们使用了 prototype 属性为 Person 类添加了一个属性,与其说是添加,不如说是销毁了原来的 Person 类,js 又重新创建了一个新的包含 walk 方法的 Person 类!而原来的 Person 类将不复存在。

这样做的效果,在各自调用 walk 方法时只会生成一次 ,不会产生副作用。

回到标题,解决了这个问题,我们要怎么继承父类的方法呢?我们一步一步来。

js 并不能实现真正的继承,为了解决这种问题,JavaScript提供了prototype 属性,来实现伪继承。

JavaScript 类的 prototype 属性代表了该类的原型对象。

在默认情况下,JavaScript 类的 prototype 属性值是一个 Object 对象,将 JavaScript 类的 prototype 设为父类对象 ,可实现 JavaScript 的继承,即原型链方法

function Person(name, age) {this.name = name;this.age = age;
}
Person.prototype.sayHello = function () {console.log(this.name + "向您打招呼!");
}
var per = new Person("zkm",20);
per.sayHello();
function Student(grade) {this.grade=grade;
}
Student.prototype = new Person('ccc',25);
Student.prototype.intro = function () {console.log("%s是一名学生,读%d年级",this.name,this.grade);
}
var stu = new Student(5);
stu.name = "孙悟空";
console.log(stu instanceof Student);
console.log(stu instanceof Person);
stu.sayHello();
stu.intro();

解释代码:

首先我们定义了一个 Person 类,有两个属性实例 name,age,通过 prototype 属性为 Person 类添加了 sayHello 方法。

然后我们又定义了一个 Student 类,有一个属性实例 grade,我们想要它去继承 Person 类。

    JavaScript 类的 prototype 属性代表了该类的原型对象。

所以  Student.prototype = new Person('ccc',25); ,Student 类的原型就是 Person 类,这样它就获得了 Person 类的属性和方法。

执行结果:

我们能看到 stu 对象既属于 Student 也属于 Person。

这样我们就成功继承了父类,但是这种做法有一种缺点,就是从父类继承过来的实例属性我们必须为它赋值,有多少就得赋多少个值,这样在创建多个对象时,就很麻烦,所以这也不是最好的方法,在介绍最正确的方法之前,我们还得了解另一种继承的方法。

构造器实现伪继承(对象冒充)

直接上代码:

//person类
function Person(name, age) {this.name = name;this.age = age;this.sayHello = function () {console.log(this.name + "向您打招呼!");}
}
var per = new Person("zkm",20);
per.sayHello();
//学生类
function Student(name ,age ,grade) {this.inherit = Person;//调用person类的构造方法,赋给实例变量this.inherit(name,age);this.grade=grade;
}
Student.prototype.intro = function () {console.log("%s是一名学生,读%d年级",this.name,this.grade);
}
var stu = new Student("孙悟空",20,5);
console.log(stu instanceof Student);
console.log(stu instanceof Person); //false,伪继承
stu.sayHello();
stu.intro();

细心的小伙伴们已经发现了 Person 的 sayHello 方法又移到了里面。构造器继承,只会继承父类构造器里面的内容,并不会继承 prototype 后加的属性或方法。

这里可以把 子类 Student  构造器内的  this.inherit = Person; 和 this.inherit(name,age);

替换成  Person.call(this,name,age)

总结:(标准的 js 继承父类写法)

  • 不要在构造体中创建方法

  • 要为对象添加方法时,通过在外面 对象.prototype.方法名 = function(参数){方法体},来添加

  • 通过原型链的方式把父类所有的属性和方法继承过来

  • 为解决原型链的属性赋值问题,再通过构造器继承即对象冒充,再通过call和apply来把属性赋过来,就不用一个个赋值了

正确姿势:

//动物类
function animal(sex, age) {this.sex=sex;this.age=age;
}
animal.prototype.info = function () {console.log("名字叫%s,年龄是%d,性别是%s",this.name,this.age,this.sex);
}
//狗类
function Dog(sex,age,name) {this.name=name;animal.call(this,sex,age);
}
Dog.prototype = new animal();
Dog.prototype.bark = function () {document.write("wangwangwang<br/>");
}
//猫类
function Cat(sex,age,name) {this.name=name;animal.call(this,sex,age);
}
Cat.prototype = new animal();
Cat.prototype.bark = function () {document.write("miaomiaomiao<br/>");
}
var dog = new Dog("男",2,"旺财");
dog.info();
dog.bark();
var cat = new Cat("女",3,"喵喵");
cat.info();
cat.bark();

JavaScript 继承父类方法的正确姿势相关推荐

  1. python-类的继承和多态-继承父类方法和属性的多种方法-继承多个类,继承顺序的研究

    一.Reference Python interview - override & overload_加藤蜀黍的博客-CSDN博客 Python:类的继承,调用父类的属性和方法基础详解_奥卡姆 ...

  2. 子类怎么继承父类方法中的变量_JavaOOP_04 封装 继承

    一.封装 概念:隐藏程序内部的具体实现细节,对外提供接口,从而提高程序的安全性. 高内聚,低耦合. 使用封装的步骤: 1.属性私有化,使用private访问修饰符进行修饰 2.对外提供 setter/ ...

  3. 子类怎么继承父类方法中的变量_关于继承的那些事!

    第二阶段 JAVA面向对象 第二章 继承 其实在我们面向对象这一阶段的学习中,我们就是围绕Java的三大特性(封装.继承.多态)来讲解的,在上一掌内容中我们讲解了一部分封装的有关知识,今天我们来重点学 ...

  4. 面向对象之继承-5种JavaScript继承的方法

    今天我们讨论一下常用的几种继承方法:首先我们创建一个动物函数Animal:function Animal () {this.species = '动物'}再写准备名叫猫咪的函数Cat: functio ...

  5. 【Python】继承、父类、子类、方法重写、子类调用父类方法、super()函数、多继承

    Python继承 2021/6/21 周一 学习内容:父类.子类.方法重写.子类调用父类方法.super()函数.多继承 Python入门,主要是看 菜鸟教程.w3school 网站,以及电子工业出版 ...

  6. java 隐藏父类方法,java 子类继承父类成员变量的隐藏、实现方法的重写

    成员变量的隐藏和方法的重写 Goods.java public class Goods { public double weight; public void oldSetWeight(double ...

  7. javascript中子类如何继承父类

    参考阮一峰的文章:http://javascript.ruanyifeng.com/oop/inheritance.html#toc4 function Shape() {this.x = 0;thi ...

  8. Java 中子类是否只继承父类的非私有变量和方法?

    今天在 CSDN 论坛中见到有人问在 Java 中子类是否只继承父类的非私有变量和方法(原贴在此).大部分跟贴都认为这句话是正确的,但是对于这个问题背后的本质理解却是错误的. 首先我们明确一下&quo ...

  9. js继承java方法吗_你知道JavaScript的继承吗?

    导读: 在ES6 之前js中是并没有extends继承,就像是java的单继承继承,我们通过多实现的方法模拟java的多继承,所以我们也可以同通过,利用构造函数和原型对象实现来实现JavaScript ...

最新文章

  1. 转发,脑机接口领域又一重要成果!
  2. [Python3网络爬虫开发实战] 7-动态渲染页面爬取-4-使用Selenium爬取淘宝商品
  3. Java7之线程池ForkJoinPool
  4. ASP.NET 中处理页面“回退”的方法
  5. script 放置最佳位置以及 html 执行顺序
  6. hive 语句总结_Hive常用命令总结
  7. 就业寒冬,从拉勾招聘看Python就业前景
  8. niginx的高可用配置(HA)
  9. codeblocks快速注释多行
  10. 浅析Hibernate映射(三)——继承映射
  11. MySQL数据库远程连接开启方法
  12. Win32 SDK创建ListView控件
  13. LeetCode 852 Peak Index in a Mountain Array 解题报告
  14. RS422-RS485-RS232标准接线
  15. 《植物大战僵尸》游戏数据修改
  16. Excel实战之单元格合并与拆分
  17. 小组取什么名字好_起名字大全宝宝起名字:起名字免费:女孩姓赵取什么名字好...
  18. 海事监管新模式 | 智慧舰船三维可视化管理
  19. 这个电脑用显微镜才能看清:却能让假货无处遁形
  20. 我最喜欢的五款手机APP 简直就是生活的小帮手

热门文章

  1. 用C语言写羊了个羊(二)
  2. 关于Ubuntu下传感器导致屏幕反转的问题
  3. 生成50道100以内加法/减法算式的习题_软件构造_羊卓的杨
  4. python turtle画烟花_怎么用python3画烟花?代码是什么?
  5. String的contains方法
  6. 使用 Unicode Math 键入/输入 无穷符号 infinite/infinity \infty
  7. 一把钥匙与三道门:麒麟810背后的AI棋局
  8. 火狐(Firefox)浏览器用户,你们的密码可能已经泄露
  9. linux常用命令(65):killall命令
  10. 无线网卡软AP掉线解决方法