理解JS原型以及实现继承
来源:互联网 发布:python pyqt5下载 编辑:程序博客网 时间:2024/05/19 09:50
一.理解原型
当创建了一个函数的时候,就会为该函数创建一个原型对象,并通过prototype属性指向这个原型对象。而且当使用该构造函数创建一个新实例后,该实例内部将包含一个内部属性proto,也指向这个原型对象。
function Person(name) { this.name = name; this.likething = ['eat', 'play']; this.getName = function () { return this.name; } } Person.prototype.getAge = function () { return "this prototype method getAge"; } var person1 = new Person("helong"); var person2 = new Person("jerry"); console.log(Person.prototype); console.log(person1);
下图是JS对象的引用关系图,注意箭头指向的是对象,而不是某个属性。
下图为在谷歌浏览器中打印出来的结果:
二.实现继承
2.1 使用原型链
原型链是js实现继承的主要方法,其基本原理就是让一个对象的原型对象等于另一个类型的实例,这样子类型通过搜索原型链便可以调用父类型的属性和方法。
使用原型链继承存在两个缺点:
1.原型属性会被所有实例共享,某实例对原型的修改会反应到另一个实例上面。如下代码所示,reader1和reader2实例共享likething和name属性。
2.在创建子类型的实例时,不能向超类型的构造函数中传递参数。实际上是没办法在不影响其他实例对象的情况下向超类对象传递参数,因为原型是多个实例共享的。
function Person(){ this.name = 'a default name'; this.likething = ['eat' , 'play']; this.getName = function(){ return this.name; } }; function Reader(){ } Reader.prototype = new Person(); Reader.prototype.constructor = Reader; var reader1 = new Reader(); var reader2 = new Reader(); alert(reader1.likething);//eat,play reader1.likething.push('code'); alert(reader2.likething);//eat,play,code console.log(Reader.prototype); console.log(reader1);
关系图如下:
打印结果如下:
2.2 借用构造函数(使用call或apply),也叫类式继承
采用此种方式,两个实例之间分别拥有各自的属性。解决了第一种方式的实例共享问题,而且也可以向构造函数中传递参数。
缺点在于:
这个时候在超类的原型中定义的方法就不能被子类所访问到了,如getAge()方法。
function Person(name){ this.name = name; this.likething = ['eat' , 'play']; this.getName = function(){ return this.name; } }; Person.prototype.getAge = function(){ alert("你妹啊!"); } function Reader(name){ Person.call(this,name); } var reader1 = new Reader("何"); var reader2 = new Reader("龙"); reader1.getAge();//报错 console.log(Person.prototype); console.log(Reader.prototype); console.log(reader1);
2.3 组合继承
综合上述两种方式的优缺点,组合继承方式使用原型链方式实现对原型属性和方法的继承,而通过构造函数来实现对实例属性的继承。
这样,既通过在原型上定义方法实现方法的复用,又能够保证每个实例都有它自己的属性,而且超类的原型中定义的方法也能被子类所访问到了,
也就是复用的定义在原型上,私有的定义在构造函数中。
function Person(name , age){ this.name = name; this.age = age; this.likething = ['eat' , 'play'], this.getName = function(){ return this.name; } }; Person.prototype.getAge = function(){ return this.age; }; function Reader(name , age){ Person.call(this,name,age); } Reader.prototype = new Person("default name"); Reader.prototype.constructor = Reader; var reader1 = new Reader("何", 18); var reader1 = new Reader("龙" ,19); console.log(Person.prototype); console.log(Reader.prototype); console.log(reader1);
0 0
- 理解JS原型以及实现继承
- js核心基础之理解原型对象以及原型继承(一)
- js核心基础之理解原型对象以及原型继承(二)
- 深入理解JS继承和原型链
- 关于js原型继承的理解
- JS 从原型与继承理解对象
- js 的原型链 以及伪继承
- 彻底理解JS原型以及构造函数
- 对于js原型和原型链继承的简单理解(第一种,原型链继承)
- js中通过原型实现继承
- 【web前端-理解js原型】理解Javascript中的原型对象、原型链和继承
- js实现继承的练习 prototype原型继承
- js中原型,原型链,原型链继承的个人理解
- JS:原型、原型链、继承
- 原型链以及继承
- 快速理解JS中的继承与原型链
- js 原型继承
- js原型、继承
- python lambda表达式
- Android知识点随记
- 技术摘要
- iOS中NSRunLoop的模式
- 海马汽车经销商管理系统技术解析(十一)前台接待模块的接车功能
- 理解JS原型以及实现继承
- 【hbase】——HBase 写优化之 BulkLoad 实现数据快速入库
- Hadoop学习(2)
- JavaScript开发人员需了解的工具内容
- Oracle基础(七):数据库事务
- 搭建嵌入式开发环境总结
- 大数据引发的联想--人工智能
- 微软100题(58)倒叙输出链表
- 8.18在类模板外定义成员函数,实现3个数求和