《JavaScript高级程序设计第六章--面向对象》section_03

这一部分主要讲讲有关继承的问题。

6.3  继承

  许多面向对象语言比如java都支持两种继承方式:接口继承(只继承方法签名)和实现继承(继承实际的方法);由于函数没有签名,在ECMAScript中只能支持实现继承。实现继承主要依靠原型链。

  6.3.1 原型链

    基本思想:利用原型让一个引用类型继承另一个引用类型的属性和方法。

    回顾一下构造函数、原型和实例的关系:每个构造函数都有一个原型对象,原型对象都包含一个指向构造函数的指针,而实例都包含一个指向原型对象的内部指针。

    所以,试想一下,我们让原型对象等于另一个类型的实例,结果原型对象将包含一个指向另一个原型的指针,相应地,另一个原型中也包含着一个指向另一个构造函数的指针;看图和例子吧

function SuperType(){
       this.property = true;
}
SuperType.prototy.getSuperValue = function(){
       return this.property;
};

function SubType(){
       this.subproperty = false;
}
//继承了SuperType
SubType.prototype = new SuperType();//SubType.prototype 是SuperType的实例,其内部指针自然指向SuperType的原型
SubType.prototype.getSubvalue = function(){
       return this.subproperty;
};
var instance = new SubType();
alert(instance.getSuperValue);

    分别定义了两个类型,都有各自方法和属性;继承是通过创建SuperType的实例,并将该实例赋给SubType.prototype实现的。本质是重写原型对象,代之以一个新类型的实例。(注意是先重写后创建新实例var        instance = new SubType())。使得原来存在于Supertype的实例中所有的属性和方法,现在也存在于SubType.prototype中。继承了属性和方法,也可以自己添加方法。

注意,红框和绿框所标注的,其SubType.prototype内部还有一个指针,指向SuperType的原型;property位于SubType.prototype,因为SubType.prototype是SuperType的一个实例属性。

    此外,要注意instance.constructor(注疑问,原型对象才有constructor难道不是Subtype.prototype.constructor)现在指向的是SuperType。因为SubType的原型指向了另一个对象—>SuperType的原型,而这个原型对象的constructor属性指向的是SuperType,记住一切来自引用。

    所有引用类型默认都继承了Object,也是通过原型链。所以有当调用instance.toString()时,实际上调用的是保存在Object.prototype中的那个方法。

    如何确定原型和实例的关系,有两种。1)采用instanceof  2)采用isPrototypeof()方法;如下例子

      alert(Object.prototype.isPrototypeof(instance));//true

      alert(SuperType.prototype.isPrototypeof(instance));//true

      alert(SubType.prototype.isPrototypeof(instance));//true

    谨慎地定义方法

      在子类有时候需要覆盖超类型中的某一个方法或需要添加超类型中不存在的某个方法。但不管怎样,给原型添加方法的代码一定要放在替换原型的语句之后。(注:因为如果在之前的话,被洗刷掉了,原型引用的地方是别处父级Supertype.prototype).还有一点注意,在通过原型链实现继承时,不能使用对象字面量创建原型方法。因为会重写原型链,切断联系。

        function SuperType(){
            this.property = true;//父类属性
        }

        SuperType.prototype.getSuperValue = function(){//父类原型链的方法
            return this.property;
        };

        function SubType(){
            this.subproperty = false;
        }

        //inherit from SuperType//创建父类实例给子类的原型链(XXXX)
        SubType.prototype = new SuperType();

        //new method添加新方法
        SubType.prototype.getSubValue = function (){
            return this.subproperty;
        };

        //override existing method覆盖超类型中的方法
        SubType.prototype.getSuperValue = function (){
            return false;
        };

        var instance = new SubType();
        alert(instance.getSuperValue());   //false

    原型链的问题

        问题1:前面街上包含引用类型值的原型属性会被所有实例共享。在通过原型来实现继承是,原型实际上会编程另一个类型的实例。  

        function SuperType(){
            this.colors = ["red", "blue", "green"];
        }

        function SubType(){
        }

        //inherit from SuperType
        SubType.prototype = new SuperType();

        var instance1 = new SubType();
        instance1.colors.push("black");
        alert(instance1.colors);    //"red,blue,green,black"

        var instance2 = new SubType();
        alert(instance2.colors);    //"red,blue,green,black"

        问题2:在创建子类型的实例时,不能像超类型的构造函数中传递参数。(实际上,应该说是没有办法在不影响所有对象实例的情况下,给超类型的构造函数床底参数。)所以实践中很少单独使用原型链。

    下一部分介绍,实践中的继承技术。

    

时间: 2024-10-21 18:11:48

《JavaScript高级程序设计第六章--面向对象》section_03的相关文章

JavaScript高级程序设计 第六章 面向对象程序设计

面向对象程序设计 ECMA-262将对象定义为:“无序属性的集合,其属性可以包含基本值.对象或者函数.”严格来讲,这就相当于说对象是一组没有特定顺序的值.对象的每个属性和方法都有一个名字,而每个名字都映射到一个值. 6.1理解对象 创建对象的最简单方式就是创造一个Object实例,然后再为它添加属性和方法,如下所示: var person = new Object(); person.name = 'yyg'; person.age = 23; person.job = 'student; pe

JavaScript高级程序设计-第六章面向对象的程序设计

创建对象主要的两种形式,创建Object实例和创建对象字面量 对象包含属性和方法 数据 .属性有四个特性,特性是为了描述属性行为的,他们是: Configurable(可配置的)是否能删除或是否能修改为访问器属性 Enumerable(枚举)是否能够for-in Writeable(可写)能否修改属性值 Value(值)默认为undefined,从这个位置上读数据或把新值保存到这个位置上 eg: var person = {}'; Object.defineproperty(person,"na

读书笔记 - js高级程序设计 - 第六章 面向对象的程序设计

EcmaScript有两种属性 数据属性 和 访问器属性 数据属性有4个特性 Configurable Enumerable Writable Value 前三个值的默认值都为false 举例 Object.defineProperty( person, "name", { writable:false, value:"niko"} ) ; 一旦属性定义为不可配置的,就不能再把它变回可配置的了 读取属性 的特性 var descriptor  = Object.ge

javascript高级程序设计 第十三章--事件

javascript高级程序设计 第十三章--事件js与HTML的交互就是通过事件实现的,事件就是文档或浏览器窗口中发生的一些特定的交互瞬间. 事件流:事件流描述的是从页面中接收事件的顺序,IE的是事件冒泡流,Netscape的是事件捕获流,这个两个是完全相反的事件流概念. 事件冒泡:由最具体的元素接收,然后逐级向上传播到更高级的节点,即事件沿DOM树向上传播,直到document对象. 事件捕获:不大具体的节点应该更早接收到事件,相当于沿DOM节点树向下级传播直到事件的实际目标,在浏览器中,是

javascript高级程序设计 第十一章--DOM扩展

javascript高级程序设计 第十一章--DOM扩展DOM最主要的扩展就是选择符API.HTML5和Element Traversal Selectors API:定义了两个方法 querySelector() 和 querySelectorAll(),能够基于CSS选择符从DOM中取得元素.querySelector()方法接收一个CSS选择符,返回该模式匹配的第一个元素,querySelectorAll()接收的参数一样,但是返回NodeList实例: matchesSelector()

Javascript高级程序设计——第三章:基本概念

javascript高级程序设计——第三章:基本概念 一.语法 EMCA-262通过叫做ECMAScript的“伪语言”为我们描述了javascript实现的基本概念 javascript借鉴了C的语法,区分大小写,标示符以字母.下划线.或美元符号($)开头,注释可以用 // 或者/* */ 严格模式: ECMAScript 5引入了严格模式,在严格模式下不确定的行为将得到处理,通过在顶部添加 “use strict”来启用严格模式: function fuc(){ "use strict&qu

《JavaScript高级程序设计第五章--引用类型》之Object对象和array对象

这一章主要就是介绍各种内置对象的用法,认识其经常用到的属性和方法. 5.1Object类型 创建objec的方式,一种是new Object(),一种是对象字面量(简化创建包含大量属性的对象的过程) var person = { name = "Nicholas"; age = 27 };//最后一个属性不必添加逗号,ie7等会导致错误 //在使用对象字面量语法时,属性名也可以使用字符串.这里的数值属性会自动转字符串. var person = { "name" :

读书时间《JavaScript高级程序设计》二:面向对象

接着上次的进度,开始看第6章. 第6章 面向对象的程序设计 理解对象 创建自定义对象最简单的方式就是创建一个 Object 的实例,然后为它添加属性和方法. var person = new Object(); person.name = 'xxx'; person.say = function(){ alert(this.name); } //等同于 对象字面量 var person = { name: 'xxx', say: function(){ alert(this.name); } }

javascript高级程序设计 1 ~ 3 章 部分知识点总结

第一章 javascript简介 javascript的简介,有关js的一些历史问题. js初期在不同的浏览器存在很大的兼容问题,但是慢慢的大家都在向标准靠拢,兼容问题已经好很多了. 我们通常会听到ECMAScript,它跟javascript是什么关系呢? JS = ES + BOM(浏览器对象模型) + DOM(文档对象模型)  ES就是对javascript的类型,值,对象,属性,函数以及程序句法和语义,DOM就是ES运行在浏览器环境的时候,浏览器为其提供的扩展以实现更多更具体的功能(we