`
siashuayongsheng
  • 浏览: 121971 次
  • 性别: Icon_minigender_1
  • 来自: 郑州
社区版块
存档分类
最新评论

Javascript Prototype

阅读更多
JavaScript通过一种链接机制来支持继承,而不是通过完全面向对象语言(如Java)所支持的基于类的继承模型。每个JavaScript对象都有一个内置的属性,名为prototype。prototype属性保存着对另一个JavaScript对象的引用,这个对象作为当前对象的父对象。

  当通过点记法引用对象的一个函数或属性时,倘若对象上没有这个函数或属性,此时就会使用对象的prototype属性。当出现这种情况时,将检查对象prototype属性所引用的对象,查看是否有所请求的属性或函数。如果prototype属性引用的对象也没有所需的函数或属性,则会进一步检查这个对象(prototype属性引用的对象)的prototype属性,依次沿着链向上查找,直到找到所请求的函数或属性,或者到达链尾,如果已经到达链尾还没有找到,则返回undefined。从这个意义上讲,这种继承结构更应是一种“has a”关系,而不是“is a”关系。

  如果你习惯于基于类的继承机制,那么可能要花一些时间来熟悉这种prototype机制。prototype机制是动态的,可以根据需要在运行时配置,而无需重新编译。你可以只在需要时才向对象增加属性和函数,而且能动态地把单独的函数合并在一起,来创建动态、全能的对象。对prototype机制的这种高度动态性可谓褒贬不一,因为这种机制学习和应用起来很不容易,但是一旦正确地加以应用,这种机制则相当强大而且非常健壮。

这种动态性与基于类的继承机制中的多态概念异曲同工。两个对象可以有相同的属性和函数,但是函数方法(实现)可以完全不同,而且属性可以支持完全不同的数据类型。这种多态性使得JavaScript对象能够由其他脚本和函数以统一的方式处理。



下面是一个例子,其中,BaiduBlog类继承自Blog类。代码如下所示:

<script language="JavaScript" type="text/javascript">
function Blog(){
   var loginName = "anonymous"; // 私有成员,使用var声明
   var pwdProtectedEmail = "anonymous@website.com"; // 私有成员,使用var声明
   // 下面定义的是访问私有成员的公有方法
   this.setLoginName = function(aLoginName){
    loginName = aLoginName;
   }
   this.setPwdProtectedEmail = function(aPwdProtectedEmail){
    pwdProtectedEmail = aPwdProtectedEmail;
   }
   this.getLoginName = function(){
    return loginName;
   }
   this.getPwdProtectedEmail = function(){
    return pwdProtectedEmail;
   }
}
Blog.prototype.provider = "";
Blog.prototype.providerWebsite = "";
Blog.prototype.copyRight = "";
Blog.prototype.displayName = "";
Blog.prototype.blogName = "";
Blog.prototype.description = "";
Blog.prototype.url = "http://";
Blog.prototype.newBlog = function(){
   return new Blog();
};
Blog.prototype.generateBlogURL = function(){};
Blog.prototype.getGreetins = function(){
   var words = "欢迎使用" + this.provider + "提供的博客服务,谢谢!<BR>";
   return words;
};
Blog.BELONGS_COUNTRY = "中国"; // 常量
Blog.WEB_RULES = "WEB 2.0";


function BaiduBlog(){
   BaiduBlog.prototype.constructor(); // 调用基类的构造函数
};
BaiduBlog.prototype = new Blog(); // 绑定
BaiduBlog.prototype.provider = "百度";
BaiduBlog.prototype.providerWebsite = "www.baidu.com";
BaiduBlog.prototype.copyRight = "2008<B> 百度 </B>版权归百度所有";
BaiduBlog.prototype.getBaiduSearcherInYourBlog = function(displayName){
   var searcherURL = "你可以直接使用下面的链接进行站内检索:<BR>";
   searcherURL += "http://hi.baidu.com/sys/search?type=0&sort=1&entry=1&region=2&hi=";
   searcherURL += displayName;
   searcherURL += "&word=";
   return searcherURL;
};
BaiduBlog.prototype.generateBlogURL = function(){   // 生成用户博客的地址URL
   var url = "http://hi.baidu.com/";
   url += this.displayName; // 访问继承自基类Blog而来的displayName
   return url;
};
BaiduBlog.prototype.getGreetins = function(){   // 该方法重写了基类Blog中的getGreetins()方法
   var words = Blog.prototype.getGreetins.call(this); // 调用基类中被重写的该方法getGreetins
   words += "如果您在使用 " + this.provider + "博客!如果您在使用过程中遇到问题,请联系管理员。<BR>";
   words += "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;";
   words += "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;";
   words += "百度管理员Email : admin@baidu.com";
   return words;
};


var myBaiduBlog = new BaiduBlog();
myBaiduBlog.displayName = "shirdrn";
myBaiduBlog.setLoginName("s2008xyk");
myBaiduBlog.blogName = "异域王者";
myBaiduBlog.description = "虽体解吾犹未变兮,岂余心之可惩。";
myBaiduBlog.setPwdProtectedEmail("shirdrn@protected.com");


var belongsArea = Blog.BELONGS_COUNTRY;
var blogRules = Blog.WEB_RULES;
var provider = myBaiduBlog.provider;
var providerWebsite = myBaiduBlog.providerWebsite;
var greetins = myBaiduBlog.getGreetins("百度");
var copyRight = myBaiduBlog.copyRight;
var logName = myBaiduBlog.getLoginName();
var pwdProtectedEmail = myBaiduBlog.getPwdProtectedEmail();
var blogName = myBaiduBlog.blogName;
var description = myBaiduBlog.description;
var url = myBaiduBlog.generateBlogURL();
var searcher = myBaiduBlog.getBaiduSearcherInYourBlog("shirdrn");

document.write("<B>所在地区 : </B>" + belongsArea + "<BR>");
document.write("<B>博客规范 : </B>" + blogRules + "<BR>");
document.write("<B>供应商名 : </B>" + provider + "<BR>");
document.write("<B>供应商网 : </B>" + providerWebsite + "<BR>");
document.write("<B>博客问候 : </B>" + greetins + "<BR>");
document.write("<B>博客版权 : </B>" + copyRight + "<BR>");
document.write("<B>登录帐户 : </B>" + logName + "<BR>");
document.write("<B>保护邮箱 : </B>" + pwdProtectedEmail + "<BR>");
document.write("<B>博客名称 : </B>" + blogName + "<BR>");
document.write("<B>博客描述 : </B>" + description + "<BR>");
document.write("<B>博客链接 : </B>" + url + "<BR>");
document.write("<B>我的搜索 : </B>" + searcher + "<BR>");

</script>

运行结果如下所示:

所在地区 : 中国
博客规范 : WEB 2.0
供应商名 : 百度
供应商网 : www.baidu.com
博客问候 : 欢迎使用百度提供的博客服务,谢谢!
如果您在使用 百度博客!如果您在使用过程中遇到问题,请联系管理员。
                         百度管理员Email : admin@baidu.com
博客版权 : 2008 百度 版权归百度所有
登录帐户 : s2008xyk
保护邮箱 : shirdrn@protected.com
博客名称 : 异域王者
博客描述 : 虽体解吾犹未变兮,岂余心之可惩。
博客链接 : http://hi.baidu.com/shirdrn
我的搜索 : 你可以直接使用下面的链接进行站内检索:
http://hi.baidu.com/sys/search?type=0&sort=1&entry=1®ion=2&hi=shirdrn&word=


对JavaScript实现继承,借助上面代码进行说明和总结一下:

1、在一个类中设定其成员为私有,使用var声明。只要在类的构造函数中使用var声明了成员变量,那么就不可以通过该函数对象的对象实例来直接访问该私有成员(不能使用对象实例名加上“.”加上该私有成员变量名来访问),想要访问它,必须构造一个共有的方法来提供访问接口,例如上面程序中,loginName 被使用var声明了,即为私有成员,只能通过编写的“Setter/Getter”和来设置或者读取它的数据,如下Blog类定义所示:

function Blog(){
   var loginName = "anonymous"; // 私有成员,使用var声明
   var pwdProtectedEmail = "anonymous@website.com"; // 私有成员,使用var声明
   // 下面定义的是访问私有成员的公有方法
   this.setLoginName = function(aLoginName){
    loginName = aLoginName;
   }
   this.setPwdProtectedEmail = function(aPwdProtectedEmail){
    pwdProtectedEmail = aPwdProtectedEmail;
   }
   this.getLoginName = function(){
    return loginName;
   }
   this.getPwdProtectedEmail = function(){
    return pwdProtectedEmail;
   }
}

2、子类继承基类的一般格式如下:

function BaseClass(){} // 基类的定义

……

function SubClass(){
   BaseClass.prototype.constructor();   // 调用基类的构造函数,这里使用prototype对象的构造方法constructor()
};
BaiduBlog.prototype = new Blog(); // 进行绑定,使子类SubClass继承自基类BaseClass


3、子类继承自基类,基类的成员变量具有默认值,子类在构造对象实例的时候,必须修改对应属性的值,否则子类对象实例的属性值是基类的属性的默认值。

子类继承自基类,那么子类也继承了基类的成员变量和成员方法,除了私有成员以外,可以直接通过this关键字来访问。

4、对于子类重写了基类的成员方法,那么子类的对象实例在需要访问基类的该成员方法时,可以通过下面的方式来实现:

function BaseClass(){} // 基类的定义
BaseClass.prototype.someMethod(){
   do what BaseClass's instance should do;
}


function SubClass(){
   BaseClass.prototype.constructor();   // 调用基类的构造函数,这里使用prototype对象的构造方法constructor()
}
SubClass.prototype.callMethod(){
  BaseClass.prototype.someMethodc.call(this);
   do what SubClass's instance should do;
}

因为基类是最高层的抽象,基类中某些高级的抽象同样适合子类,而子类又具有自己的某些特征,所以子类在重写基类的成员方法的时候,可以先调用基类的该同名成员方法,然后在添加自己特有的动作或者特征。

通过上面,在子类的someMethodc()成员方法中执行BaseClass.prototype.someMethodc.call(this);这句,就可以获取到基类的对象实例执行该方法所得到的数据,然后子类又执行了一系列子类对象实例应该执行的操作:do what SubClass's instance should do;。

5、在类的构造函数之外使用prototype定义类的成员,都是共有的,可以直接使用“.”运算符来访问。在类的构造函数体之内,使用this.来指定的成员就是共有的成员。
分享到:
评论

相关推荐

    javascript prototype文档.rar

    JavaScript中的原型(Prototype)是理解JavaScript继承机制的关键概念。它是一种对象属性,允许一个对象访问并继承另一个对象的属性和方法。在这个“javascript prototype文档”中,我们可以期待深入学习JavaScript...

    javascript prototype原型操作笔记.docx

    ### JavaScript Prototype原型操作知识点 #### 一、Prototype基础概念 **Prototype** 在 JavaScript 中是一个非常重要的概念,它支持面向对象编程中的继承特性。每个 JavaScript 对象都有一个内部属性 `[...

    javascript Prototype 对象扩展.docx

    ### JavaScript Prototype 对象扩展 #### 一、简介与背景 在JavaScript中,`prototype`是一个非常重要的概念,尤其是在面向对象编程(OOP)方面。通过利用`prototype`,开发者能够更高效地管理对象间的共享属性和...

    JavaScriptprototype的深度探索不是原型继承那么简单.pdf

    JavaScriptprototype的深度探索不是原型继承那么简单.pdf

    JavaScript的prototype

    JavaScript中的`prototype`是一个核心概念,它涉及到对象继承和函数原型。在JavaScript中,每创建一个函数,该函数就会自动获得一个名为`prototype`的属性,这个属性是一个对象,用于实现对象间的继承。同时,每个...

    JavaScript_Prototype(源代码+中文手册).rar

    JavaScript Prototype 是一种重要的编程概念,尤其在Web开发中不可或缺。这个压缩包文件“JavaScript_Prototype(源代码+中文手册).rar”包含了关于JavaScript原型的源代码和中文手册,为学习和理解这一主题提供了...

    JavaScript prototype属性详解

    JavaScript中的`prototype`属性是面向对象编程的关键特性之一,它关联了函数(特别是构造函数)与实例之间的继承关系。每个函数都有一个`prototype`属性,这个属性是一个对象,包含了所有实例共享的方法和属性。当...

    javascript prototype原型详解(比较基础)

    javascript的prototype原型简单介绍: prototype原型是javascript中特别重要的概念,属于必须要掌握,如果没有良好的掌握的话,进一步用好或者学好js基本是不可能的实现的事情,并且此概念稍有难度,可能对于初次接触...

    Advanced JavaScript (closures,prototype,inheritance)

    JavaScript,作为一种广泛应用于Web开发的脚本语言,其高级特性如闭包(closures)、原型(prototype)和继承(inheritance)是理解其精髓的关键。本文将深入探讨这些概念,帮助开发者更好地掌握JavaScript的核心。 ...

    Prototype

    Prototype 是一个广泛使用的JavaScript库,设计目的是为了简化JavaScript的开发,尤其是处理DOM操作、AJAX交互以及事件处理等方面的工作。它通过提供一系列实用的工具函数和面向对象的特性,极大地提高了JavaScript...

    javascript类库prototype.js

    Prototype.js 是一个强大的JavaScript类库,它为开发者提供了丰富的功能,使得创建具有高度互动性和Web2.0特性的富客户端页面变得更为简单。这个库的设计理念是扩展JavaScript的基础对象,提供一套统一且易于使用的...

    JavaScript prototype(原型对象)

    JavaScript prototype(原型对象) 所有的 JavaScript 对象都会从一个 prototype(原型对象)中继承属性和方法。 在前面的章节中我们学会了如何使用对象的构造器(constructor): 实例 function Person(first, ...

    JavaScript Prototype对象

    JavaScript Prototype对象是JavaScript语言中的一个核心特性,它在JavaScript 1.1版本中就已经引入,主要目的是为了实现面向对象编程的继承机制。Prototype对象允许开发者为已存在的对象类型添加新的属性和方法,...

    javascript prototype 原型链

    JavaScript中的原型链(Prototype Chain)是理解面向对象编程在JavaScript中的实现方式的关键概念。原型链是基于原型(Prototype)机制的一种实现,它允许对象继承其他对象的属性和方法。在JavaScript中,每个函数...

    JavaScript prototype对象的属性说明

    一、什么是JavaScript中对象的prototype属性 JavaScript中对象的prototype属性,是用来返回对象类型原型的引用的。我们使用prototype属性提供对象的类的一组基本功能。并且对象的新实例会”继承”赋予该对象原型的...

    javascript prototype原型操作笔记

    JavaScript中的prototype机制是其面向对象编程的核心概念之一,它允许开发者创建具有继承属性和方法的对象。在JavaScript中,几乎所有的对象都是通过某个构造函数或对象字面量创建的,而这些构造函数或对象自身都有...

    JavaScript prototype属性使用说明

    JavaScript中的prototype属性是一个非常重要的概念,它是ECMAScript规范定义的一部分,用于给对象的构造函数添加新方法或者修改现有方法。IE 4引入的prototype属性主要用于面向对象编程中,能够在不改变原有构造函数...

    JavaScript使用prototype定义对象类型

    JavaScript 使用 prototype 定义对象类型 在 JavaScript 中,prototype 是一个非常重要的概念,它提供了一套面向对象编程的基础设施,允许开发者定义对象类型和实现继承。下面我们将详细介绍如何使用 prototype ...

Global site tag (gtag.js) - Google Analytics