关于原型继承的一些问题

当我们使用原型链继承时,需要谨慎的定义原型上的方法和属性,因为这可能带来意外的结果。

一、谨慎的定义原型上的方法。
当我们想为一个构造函数的原型上定义一个方法时,一定要在更改原型后再定义,否则新的原型对象上不会有定义的这个方法,导致与我们预期的结果不同。例:

1 function superObj(){}
2 superObj.prototype.sayHi=function sayHi(){
3     console.log(‘hi‘);
4 };
5 superObj.prototype={
6     name:‘Poly‘
7 };
8 var obj=new superObj();
9 obj.sayHi();//报错!! superObj.sayHi is not a function

正确操作如下

1 function superObj(){}
2 superObj.prototype={
3     name:‘Poly‘
4 };
5 superObj.prototype.sayHi=function sayHi(){
6     console.log(‘hi‘);
7 };
8 var obj=new superObj();
9 obj.sayHi();// ‘hi‘

二、不要使用对象字面量给原型创建属性/方法。
使用对象字面量,就会新创建一个对象,并把新对象的引用地址赋值给构造函数的prototype。例

1 function superObj(){}
2 superObj.prototype={
3     sayHi:function sayHi(){
4         console.log(‘hi‘);
5     }
6 }

正确操作如下:

1 function superObj(){}
2 superObj.prototype.sayHi=function sayHi(){
3     console.log(‘hi‘);
4 }

三、对象实例与原型存在直接对应关系。
意思就是说当一个对__proto__就会保存原型的引用地址,即使构造函数的prototype发生改变,也不会对之前创建的实例中的__proto__产生影响。例

 1 function superObj(){}
 2 superObj.prototype.say=function() {
 3     console.log(‘hello‘);
 4 }
 5 var obj=new superObj();
 6 superObj.prototype={
 7     say:function() {
 8         console.log(‘world‘);
 9     }
10 };
11 var obj2=new superObj();
12 obj.say();//‘hello‘
13 obj2.say();//‘world‘

四、最好不要给原型上定义值为引用类型的属性。
如果在原型上定义值为引用类型的属性,那么所有实例都会共享该属性值(引用类型值,指向同一个对象),当其中一个实例修改该引用类型上的值或属性时,所有实例上的都会发生改变。因此值为引用类型的属性,最好在构造函数中定义。例

1 function superObj(){}
2 superObj.prototype.ary=[1,2,3];
3 var obj1=new superObj();
4 var obj2=new superObj();
5 obj1.ary[0]=0;//obj1.ary和obj2.ary指向的是同一个数组,当obj1修改此数组时,obj2.ary也会发生改变
6 console.log(obj2.ary[0]);//0

如果不想让实例共享同一个引用对象,那么就应该在构造函数中进行定义。例

1 function superObj(){
2     this.ary=[1,2,3];
3 }
4 var obj1=new superObj();
5 var obj2=new superObj();
6 obj1.ary[0]=0;//obj1.ary和obj2.ary指向的不是同一个数组,所以修改obj1.ary不会影响obj2.ary
7 console.log(obj2.ary[0]);//1
时间: 2024-12-14 18:57:31

关于原型继承的一些问题的相关文章

关于js的对象原型继承

javascript中,对象的继承是通过原型去继承. 可以这样理解:js中的对象,包含的除了属性和方法,还有一个最基本的原型__proto__对象.这个原型__proto__指向谁,这个对象就继承谁.这是最容易理解对象原型继承的一种方式. 如下面的代码: var student={ name:'zhangsan', age:21, run:function(){ return this.name+' is running!'; } }; var xiaoming={ name:'xiaoming

JS继承之原型继承

许多OO语言都支持两种继承方式:接口继承和实现继承.接口继承只继承方法签名,而实现继承则继承实际的方法.如前所述,由于函数没有签名,在ECMAScript中无法实现接口继承.ECMAScript只支持实现继承,而且其实现继承主要是依靠原型链来实现的. --摘自<JavaScript高级程序设计> 原型继承 原型链是实现原型继承的主要方法,基本思想就是利用原型让一个引用类型继承另一个引用类型的属性和方法. 实现原型链的基本模式: 1 2 3 4 5 6 7 8 9 10 11 12 13 fun

javascript继承,原型继承,借用构造函数继承,混合继承

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <% String path = request.getContextPath(); String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getS

javascript基础集锦_Json——原型继承(十)

在传统的基于Class的语言如Java.C++中,继承的本质是扩展一个已有的Class,并生成新的Subclass. 由于这类语言严格区分类和实例,继承实际上是类型的扩展.但是,JavaScript由于采用原型继承,我们无法直接扩展一个Class,因为根本不存在Class这种类型. 但是办法还是有的.我们先回顾Student构造函数: function Student(props) { this.name = props.name || 'Unnamed'; } Student.prototyp

JS中“类”继承和原型继承

类继承: 先用函数构造器创建了一个“类”Student,然后在Student原型上定义了一个方法sayHello,然后创建了一个"类“PrimaryStudent,用apply()初始化PrimaryStudent. 然后让PrimaryStudent的原型等于Student创建的对象,并把PrimaryStudent原型上的构造器指向当前”类“,即PrimaryStudent,注意红色加粗部分. 1 function Student(name){ 2 this.name = name; 3 }

JavaScript-原型&amp;原型链&amp;原型继承&amp;组合函数

小小的芝麻之旅: 今天学习了js的原型,要说原型,我们先简单说一下函数创建过程. 原型 每个函数在创建的时候js都自动添加了prototype属性,这就是函数的原型,原型就是函数的一个属性,类似一个指针.原型在函数的创建过程中由js编译器自动添加. <script type="text/javascript"> function Flower(name,area) { this.name=name; this.area=area; this.showName=myName;

JS原型继承和类式继承

类式继承(构造函数) JS中其实是没有类的概念的,所谓的类也是模拟出来的.特别是当我们是用new 关键字的时候,就使得"类"的概念就越像其他语言中的类了.类式继承是在函数对象内调用父类的构造函数,使得自身获得父类的方法和属性.call和apply方法为类式继承提供了支持.通过改变this的作用环境,使得子类本身具有父类的各种属性. JavaScript var father = function() { this.age = 52; this.say = function() { al

JS 原型继承的几种方法

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <title>Document</title> </head> <body> <script type="text/javascript"> function Person() { this.name = '老王

js原型继承

原型链: Object(构造函数) object(类型(对象)) var o = {}; alert(typeof o); //结果是object alert(typeof Object); //结果是function 每一个对象都有一个属性叫 __proto__ ,这个属性就是这个对象的原型(o. __proto__),函数可通过 函数名.prototype 获取原型,对象可以通过 对象.__proto__(双下划线)获取. 对象有原型,原型也是对象,所以原型也有原型,所有的函数都是对象,继承

JS继承,原型继承,构造函数的继承,非构造函数&quot;的继承

a.原型继承 一.new运算符的缺点 用构造函数生成实例对象,有一个缺点,那就是无法共享属性和方法.比如,在DOG对象的构造函数中,设置一个实例对象的共有属性species. function DOG(name){ this.name = name; this.species = '犬科'; } 然后,生成两个实例对象: var dogA = new DOG('大毛'); var dogB = new DOG('二毛'); 这两个对象的species属性是独立的,修改其中一个,不会影响到另一个.