原型与继承
来源:互联网 发布:java获取局域网所有ip 编辑:程序博客网 时间:2024/05/19 20:40
最近为了校招面试在刷基础,看了原型和继承又是各种懵比的样子。原型的问题参考大神博客深入理解JavaScript原型和闭包以及JavaScript面向对象编程
关于对象和函数的关系,简单说以下几点。
- 函数是一种对象,而对象是通过函数创建的。
- 函数含有prototype属性,该属性其实是属性的集合(对象),其默认属性为Constructor,Constructor指向构造函数本身。
- 对象含有_proto_属性,该属性指向创建该对象的函数的原型。即obj._proto_ === F.prototype。
接下来说说继承。
高程给了六种继承方法:原型链继承,借用构造函数继承,组合继承,原型式继承,寄生式继承,寄生组合式继承。
本文是前三种方式的笔记~
一、原型链
通过让B的原型对象成为A的实例,当构造B的实例时,该实例将实现对A中属性和方法的继承。
属性和方法,分为两种,一种是私有的,一种是公有的。在原型中定义的属性和方法是公有属性,可对其进行操作,而构造函数中的属性和方法是实例私有的属性方法。
function SuperType() { this.property = true;}SuperType.prototype.getSuperValue = function() { return this.property;};function SubType() { this.subproperty = false;}//inherit from SuperTypeSubType.prototype = new SuperType();SubType.prototype.getSubValue = function() { return this.subproperty;};var instance = new SubType();console.log(instance.getSuperValue()); //true// SubType原型继承了Supertype的属性和方法console.log(SubType.prototype); // SuperType {property: true, getSubValue: [Function]}console.log(SubType.prototype.getSuperValue());// trueconsole.log(SubType.prototype.constructor === SuperType); // trueconsole.log(SuperType.prototype.constructor === SuperType); // trueconsole.log(instance.constructor);// [Function: SuperType]弊端:
- 包含引用类型值的原型。包含引用类型值得原型属性会被所有实例共享(等会儿去翻书解决这一问题),而这也正是为什么要在构造函数中而不是在原型对象中定义属性的原因。再通过原型来实现继承时,原型实际上会变成另一个类型的实例。于是原先的实例属性也就变成了现在的原型属性。
function SuperType() { this.colors = ["red", "blue", "green"];}function SubType() {}//inherit from SuperTypeSubType.prototype = new SuperType();var instance1 = new SubType();instance1.colors.push("black");console.log(instance1.colors); //"red,blue,green,black"var instance2 = new SubType();console.log(instance2.colors); //"red,blue,green,black"// SubType.prototype中的colors属性被修改,并未影响到超类型的构造函数属性值的改变var instance3 = new SuperType();console.log(instance3.colors); // 'red, blue, green'
- 在创建子类型的实例时,不能向超类型的构造函数中传递参数。
基本思想是在子类型构造函数的内部调用超类型构造函数。即在子类型构造函数的内部调用超类型构造函数。通过使用apply()和call()在(将来)创建的对象上执行构造函数。
function SuperType (name) { this.name = name;}function SubType () { SuperType.call(this,'azure'); this.age = 29;}var instance1 = new SubType();instance1.age = 23;console.log(instance1.name, instance1.age);var instance2 = new SubType();instance2.name = 'hel';console.log(instance2.name, instance2.age);
问题:方法都在构造函数中定义,因此函数复用就无从谈起了。
三、组合继承
啦啦啦结合二者之长的来啦~组合继承的思路是使用原型链实行对原型属性和方法的继承,通过借用构造函数来实现对实例属性的继承。如此,既通过在原型上定义方法实现了函数复用,又能保证每个实例都有自己的属性。
四、比较
// case 1: 标准的组合继承 // case 2: 注释掉a、b语句,此时为原型链继承 // case 3: 注释掉b、c语句,此时为构造函数继承 function SuperType (name) { this.name = name; this.colors =['r', 'g', 'b']; } SuperType.prototype.sayName = function () { console.log(this.name); }; function SubType (name, age) { // a.这一句的作用是,SubType实例将具备SuperType构造函数中的属性 SuperType.call(this, name); this.age = age; } // c. 原型链继承 SubType.prototype = new SuperType(); // b.如果没有这一句,SubType.prototye.constructor指向SuperType SubType.prototype.constructor = SubType; SubType.prototype.sayAge = function () { console.log(this.age); } // case 1 -> 指向SubType, 包含属性name,colors,constructor,sayAge(), 虽然没有sayName, 但是沿着原型链即可找到, 即SubType.protype.sayName()是存在的。 // case 2 -> 指向SuperType, 包含属性name,colors,sayAge() // case 3 -> 指向SubType, 原型链并未改变,只是借用了构造函数, 只会对实例造成影响,并不会影响原型本身 console.log(SubType.prototype); var instance1 = new SubType('Nico', 24); // case 1 -> 指向SubType, 包含属性name, colors,age, 其中sayAge是SubType原型中的属性, sayName是创造SuperType实例(SubType原型)构造函数原型中的方法, 都可以通过原型链找到。 // case 2 -> 指向SuberType, 仅包含属性age, 其余都是构造函数原型中的方法 // case 3 -> 指向SubType, 包含属性name,colors(由构造函数继承而来), age, 并不能继承到sayName, 也就是说构造函数继承只可以继承构造函数里的属性和方法,并不会继承到原型的内容。 console.log(instance1); instance1.colors.push('y'); console.log(instance1.colors); // ['r', 'g', 'b', 'y'] instance1.sayName(); // Nico instance1.sayAge(); // 24 var instance2 = new SubType('azure', 23); console.log(instance2.colors); // ['r', 'g', 'b'] instance2.sayName(); // Azure instance2.sayAge(); // 23
欧耶~~结束~~
阅读全文
0 0
- 类继承与原型继承
- 继承与原型链
- 原型对象与继承
- JavaScript原型与继承
- 原型与继承
- 原型链与继承
- 原型与继承
- 继承与原型链
- JavaScript原型与继承
- 继承与原型链
- 继承与原型链
- 原型与继承
- 原型与继承
- 原型与继承
- 继承与原型链
- javascript原型链与原型继承
- JavaScript 原型、原型链与继承
- 原型对象与继承(原型链)
- Drools入门-----------环境搭建,分析Helloworld
- drools入门(二)-----规则引擎Drools解决汽水问题
- ButterKnife源码阅读
- 关于php基础类型的一些探讨
- Java规则引擎与其API(JSR-94)
- 原型与继承
- 规则引擎需求(捕捉业务规则需求,将需求转换为规则引擎)
- 上海-悠悠的测试教程
- 使用 Drools 规则引擎实现业务逻辑
- Oracle在2011年取得的Java主要成就
- DOM--(Element)
- 对连续数值进行指定方式离散化,计算分布,用cut函数
- 将java项目打包成jar文件
- Spring管理filter和servlet,无硬编码bean