剖析JavaScript中的原型(Prototype)

转载请注明出处:http://blog.csdn.net/horkychen

上篇提到构造函数包含一个prototype是实现继承的关键,就是原型链的概念。在JavaScript中当使用构造函数创建一个对象时,如下面的图示(来自<<JavaScript高级程序设计>>):

JavaScript为建构函数生成一个原型(Prototype)指向原型对象,包含了所有实例共享的对象。而原型中也有一个constructor指向建构函数,以起到标识的作用,说明”我是谁”.建构函数本身也是一个普通函数,只是首字母大写了。

 

当通过访问实例的属性和方法时:

   a.如果实例定义了同名的属性或方法,使用之。

   b.否则,尝试调用原型的同名属性或方法。

 

这里有一个关键的准则:

     所有在建构函数中定义的属性和方法,各个实例各自拥有一份。

     所有在原型中定义的引用类型属性(基本类型除外)和方法,各个实例将共享使用。

 

下面是一个包含建构和原型两种方式的对象创建示例:

function Person(name)

{

                this.name = name;

}

Person.prototype =

{

               
friends:["A","B"],

                introduceSelf : function()

                 {

                                 document.write("<p /> My name is "+this.name);

                                 document.write("<p /> My friends are "+this.friends);

                }

};

 

var horky = new Person("Horky");

horky.friends.push("C");

 

var arthas = new Person("Arthas");

 

horky.introduceSelf(); //My friends are A,B,C

arthas.introduceSelf(); //My friends are A,B,C

 

输出的结果是:

My name is Horky

My friends are A,B,C

 

My name is Arthas

My friends are A,B,C

认识这个特性很重要。一般我们希望类的方法可以重用,而不是各个实例再拥有一份实现,就可以放到原型的定义里面去。而对于子类需要自己定义的属性就可以放到建构函数中去。

 

既然原型也是一个对象,就可以按需要修改,比如扩展一下类的功能,随时加一个定义就可以了。

在上面代码后加入类似下面的代码:

……

horky.introduceSelf(); //My friends are A,B,C

arthas.introduceSelf(); //My friends are A,B,C

 

Person.prototype.saySomething = function(text)

{

                document.write("<p /> "+this.name+" says:"+text);

}

horky.saySomething("Hello, everyone!");

输出结果就会多一行:

Horky says:Hello, everyone!

理解了原型,我们再看一下继承。继承的要素是继承父类的属性和方法定义,而且属性可以自行更改。本身实例和原型之间就是继承关系的影子,因为访问是从下至上的。所以继承无非是要将子类的prototype变成一个指向父类原型的对象就可以了,如下图:

这就是<<JavaScript高级程序设计>>中所讲的较常用的寄生组合式继承。寄生指的是调用建构函数,组合则指的原型的运用。下面是示例代码:

function inheritPrototype(subType,superType){

var prototype=object(superType.prototype);  //创建对象

prototype.constructor=subType;                       //增强对象

subType.prototype=prototype;                          //指定对象

}

 

function SuperType(name){

this.name=name;

this.color=["red","blue","greed"];

}

 

SuperType.prototype.sayName=function(){

alert(this.name);

}

 

function SubType(name,age){

SuperType.call(this,name); //呼叫父类的建构函数

this.age=age;

}

 

inheritPrototype(SubType,SuperType); //将子类设定为继承自父类

 

SubType.prototype.sayAge=function(){ //增加一个子类方法

alert(this.age);

};

只要掌握前面所提原型的概念,JavaScript中使用很多OO的实现就很好理解了。比如所谓的模块(单件)模式之类的。

 

*<<JavaScript高级程序设计>>第3版在这段代码下(P173)附的图6-6是属于前段代码的解释,放在这段代码下实在容易让人误解。

 

 

时间: 2024-08-01 22:17:16

剖析JavaScript中的原型(Prototype)的相关文章

javascript学习笔记(九)javascript中的原型(prototype)及原型链的继承方式_基础知识

在使用面向对象编程时,对象间的继承关系自然少不了!而原型正是实现javascript继承的很重要的一种方法! 我们首先来看以下代码: 复制代码 代码如下: function person(name, age) { this.name = name; this.age = age; } person.prototype.getInfo = function() { alert("My name is "+this.name+", and I have "+this.a

详解JavaScript中基于原型prototype的继承特性_基础知识

JavaScript 中的继承比较奇葩,无法实现接口继承,只能依靠原型继承. 原型链原型就是一个对象,通过构造函数创建出来的实例会有指针指向原型得到原型的属性和方法.这样,实例对象就带有构造函数的属性方法和原型的属性方法,然后将需要继承的构造函数的原型指向这个实例,即可拥有这个实例的所有属性方法实现继承. 看下面演示代码: //声明超类,通过构造函数和原型添加有关属性和方法 function Super(){ this.property = true; } Super.prototype.get

JavaScript中的原型prototype完全解析_基础知识

   要理解JS中的prototype, 首先必须弄清楚以下几个概念    1. JS中所有的东西都是对象    2. JS中所有的东西都由Object衍生而来, 即所有东西原型链的终点指向Object.prototype   // ["constructor", "toString", "toLocaleString", "valueOf", "hasOwnProperty", "isProto

JavaScript中的原型prototype属性使用详解_基础知识

 prototype属性可以将属性和方法添加到任何对象(Number, Boolean, String 和Date等). 注:原型(Prototype)是一个全局的属性,它可以使用在几乎所有的对象.语法 object.prototype.name = value 实例: 这里有一个例子展示了如何使用原型(prototype)属性的属性添加到对象: <html> <head> <title>User-defined objects</title> <sc

JavaScript中的原型和继承详解(图文)_javascript技巧

请在此暂时忘记之前学到的面向对象的一切知识.这里只需要考虑赛车的情况.是的,就是赛车. 最近我正在观看 24 Hours of Le Mans ,这是法国流行的一项赛事.最快的车被称为 Le Mans 原型车.这些车虽然是由"奥迪"或"标致"这些厂商制造的,可它们并不是你在街上或速公路上所见到的那类汽车.它们是专为参加高速耐力赛事而制造出来的. 厂家投入巨额资金,用于研发.设计.制造这些原型车,而工程师们总是努力尝试将这项工程做到极致.他们在合金.生物燃料.制动技术

深入剖析JavaScript中的函数currying柯里化_javascript技巧

curry化来源与数学家 Haskell Curry的名字 (编程语言 Haskell也是以他的名字命名).   柯里化通常也称部分求值,其含义是给函数分步传递参数,每次传递参数后部分应用参数,并返回一个更具体的函数接受剩下的参数,这中间可嵌套多层这样的接受部分参数函数,直至返回最后结果. 因此柯里化的过程是逐步传参,逐步缩小函数的适用范围,逐步求解的过程.  柯里化一个求和函数 按照分步求值,我们看一个简单的例子 var concat3Words = function (a, b, c) {

javaScript中的原型解析【推荐】_javascript技巧

最近在学习javaScript,学习到js面向对象中的原型时,感悟颇多.若有不对的地方,希望可以指正. js作为一门面向对象的语言,自然也拥有了继承这一概念,但js中没有类的概念,也就没有了类似于java中的extends,所以,我觉得js中的继承主要依赖于js中的原型(链). 那么,原型是什么呢?我们知道js中函数亦是一种对象,当我们创建一个函数时,其实这个函数也就默认的拥有了一个属性叫做prototype,这个属型叫做原型属性,他是一个指针,指向了这个函数的原型对象,这个原型对象有一个默认的

javascript 中__proto__和prototype详解_基础知识

__proto__是内部原型,prototype是构造器原型(构造器其实就是函数) 构造器的原型(prototype)是一个对象 那什么是构造器呢? 要想创建一个对象,首先要有一个对象构造器,就像php里面一样,要想创建一个对象,首先要有一个类 构造器的实质就是一个函数,下面的问题是:如何通过这个构造器来创建一个对象呢? 答案: new 构造器构造的是对象. 一.所有构造器/函数的__proto__都指向Function.prototype,它是一个空函数(Empty function) 复制代

了解JavaScript中对象的prototype属性

一.什么是JavaScript中对象的prototype属性 JavaScript中对象的prototype属性,是用来返回对象类型原型的引用的.我们使用prototype属性提供对象的类的一组基本功能.并且对象的新实例会"继承"赋予该对象原型的操作.但是这个prototype到底是怎么实现和被管理的呢?对于对象的prototype属性的说明,JavaScript手册上如是说:所有 JavaScript内部对象都有只读的 prototype 属性.可以向其原型中动态添加功能(属性和方法