1、prototype的定义

javascript中的每个对象都有prototype属性,Javascript中对象的prototype属性的解释是:返回对象类型原型的引用。

每一个构造函数都有一个属性叫做原型。这个属性非常有用:为一个特定类声明通用的变量或者函数。

你不需要显式地声明一个prototype属性,因为在每一个构造函数中都有它的存在。你可以看看下面的例子:

function Test(){}
alert(Test.prototype); // 输出 "Object"

1.1、 原型法设计模式

原型法的主要思想是,现在有1个类A,我想要创建一个类B,这个类是以A为原型的,并且能进行扩展。我们称B的原型为A。

1.2、javascript的方法可以分为三类:

a 类方法

b 对象方法

c 原型方法

function People(name)
{
this.name=name;
//对象方法
this.Introduce=function(){
alert("My name is "+this.name);
}
}
//类方法
People.Run=function(){
alert("I can run");
}
//原型方法
People.prototype.IntroduceChinese=function(){
alert("我的名字是"+this.name);
} //测试
var p1=new People("Windking");
p1.Introduce();
People.Run();
p1.IntroduceChinese();

1.3、给prototype添加属性

就如你在上面所看到的,prototype是一个对象,因此,你能够给它添加属性。你添加给prototype的属性将会成为使用这个构造函数创建的对象的通用属性。

例如,我下面有一个数据类型Fish,我想让所有的鱼都有这些属性:livesIn="water"和price=20;为了实现这个,我可以给构造函数Fish的prototype添加那些属性。

function Fish(name, color){
this.name=name;
this.color=color;
}
Fish.prototype.livesIn="water";
Fish.prototype.price=;
var fish1=new Fish("mackarel", "gray");
var fish2=new Fish("goldfish", "orange");
var fish3=new Fish("salmon", "white");
for (int i=; i<=; i++){
alert(fish.name+","+fish.color+","+fish.livesIn+","+fish.price);
}

输出应该是:

"mackarel, gray, water, 20"
"goldfish, orange, water, 20"
"salmon, white water, 20"

你看到所有的鱼都有属性livesIn和price,我们甚至都没有为每一条不同的鱼特别声明这些属性。这时因为当一个对象被创建时,这个构造函数 将会把它的属性prototype赋给新对象的内部属性__proto__。这个__proto__被这个对象用来查找它的属性

你也可以通过prototype来给所有对象添加共用的函数。这有一个好处:你不需要每次在构造一个对象的时候创建并初始化这个函数。为了解释这一点,让我们重新来看Example DT9并使用prototype来重写它。

1.4、用prototype给对象添加函数

function Employee(name, salary){
this.name=name;
this.salary=salary;
}
Employee.prototype.getSalary=function getSalaryFunction(){
return this.salary;
}
Employee.prototype.addSalary=function addSalaryFunction(addition){
this.salary=this.salary+addition;
}
var boss1=new Employee("Joan", );
var boss2=new Employee("Kim", );
var boss3=new Employee("Sam", );

输出的结果为:

alert(boss1.getSalary());   // 输出 200000
alert(boss2.getSalary()); // 输出 100000
alert(boss3.getSalary()); // 输出 150000

子类如何重写父类的属性或方法:

function AClass(){
this.Property = ;
this.Method = function(){
alert();
}
}
function AClass2(){
this.Property2 = ;
this.Method2 = function(){
alert();
}
}
AClass2.prototype = new AClass();
AClass2.prototype.Property = ;
AClass2.prototype.Method = function(){
alert();
}
var obj = new AClass2();
alert(obj.Property);
obj.Method();

输出结果为:

//3
//

可以在对象上增加属性或方法

function Aclass(){
this.Property = ;
this.Method = function(){
alert();
}
}
var obj = new Aclass();
obj.Property2 = ;
obj.Method2 = function(){
alert();
}
alert(obj.Property2);
obj.Method2();

输出结果为:

//2
//
在外部不能通过prototype改变自定义类型的属性或方法。该例子可以看到:调用的属性和方法仍是最初定义的结果。即当原型方法和对象方法在调用相同的属性和函数时,会执行对象方法里面的属性和函数。
function Aclass(){
this.Property = ;
this.Method = function(){
alert();
}
}
Aclass.prototype.Property = ;
Aclass.prototype.Method = function{
alert();
}
var obj = new Aclass();
alert(obj.Property);
obj.Method();

输出结果为:

//1
//

1.5、A.prototype = new B();

理解prototype不应把它和继承混淆。A的prototype为B的一个实例,可以理解A将B中的方法和属性全部克隆了一遍。A能使用B的方法和属性。这里强调的是克隆而不是继承。可以出现这种情况:A的prototype是B的实例,同时B的prototype也是A的实例。

先看一个实验的例子:

function baseClass(){
this.showMsg = function(){
alert("baseClass::showMsg");
}
}
function extendClass(){}
extendClass.prototype = new baseClass();
var instance = new extendClass();
instance.showMsg(); // 显示baseClass::showMsg

我们首先定义了baseClass类,然后我们要定义extentClass,但是我们打算以baseClass的一个实例为原型,来克隆的extendClass也同时包含showMsg这个对象方法。

extendClass.prototype = new baseClass()就可以阅读为:extendClass是以baseClass的一个实例为原型克隆创建的。

那么就会有一个问题,如果extendClass中本身包含有一个与baseClass的方法同名的方法会怎么样?

下面是扩展实验2:

function baseClass(){
this.showMsg = function(){
alert("baseClass::showMsg");
}
} function extendClass(){
this.showMsg =function (){
alert("extendClass::showMsg");
}
}
extendClass.prototype = new baseClass();
var instance = new extendClass(); instance.showMsg();//显示extendClass::showMsg

实验证明:函数运行时会先去本体的函数中去找,如果找到则运行,找不到则去prototype中寻找函数。或者可以理解为prototype不会克隆同名函数

那么又会有一个新的问题:如果我想使用extendClass的一个实例instance调用baseClass的对象方法showMsg怎么办?

答案是可以使用call:

extendClass.prototype = new baseClass();
var instance = new extendClass(); var baseinstance = new baseClass();
baseinstance.showMsg.call(instance);//显示baseClass::showMsg

这里的baseinstance.showMsg.call(instance);阅读为“将instance当做baseinstance来调用,调用它的对象方法showMsg”

好了,这里可能有人会问,为什么不用baseClass.showMsg.call(instance);

这就是对象方法和类方法的区别,我们想调用的是baseClass的对象方法

1.6、对象方法与通过new创建对象的重要区别

这个区别就是function定义的方法(对象方法)有一个prototype属性,使用new生成的对象就没有这个prototype属性。也就是prototype属性是对象方法或者构造方法的专有属性。 prototype属性又指向了一个prototype对象,注意prototype属性与prototype对象是两个不同的东西,要注意区别。在prototype对象中又有一个constructor属性,这个constructor属性同样指向一个constructor对象,而这个constructor对象恰恰就是这个function函数本身。如下所示:

function Person(name)
{
this.name=name;
this.showMe=function()
{
alert(this.name);
}
};
var one=new Person('js');
alert(one.prototype)//undefined
alert(typeof Person.prototype);//object
alert(Person.prototype.constructor);//function Person(name) {...};

最后,下面这个代码如果理解清晰,那么这篇文章说的就已经理解了:

<script type="text/javascript">

function baseClass()
{
this.showMsg = function()
{
alert("baseClass::showMsg");
} this.baseShowMsg = function()
{
alert("baseClass::baseShowMsg");
}
}
baseClass.showMsg = function()
{
alert("baseClass::showMsg static");
} function extendClass()
{
this.showMsg =function ()
{
alert("extendClass::showMsg");
}
}
extendClass.showMsg = function()
{
alert("extendClass::showMsg static")
} extendClass.prototype = new baseClass();
var instance = new extendClass(); instance.showMsg(); //显示extendClass::showMsg
instance.baseShowMsg(); //显示baseClass::baseShowMsg
instance.showMsg(); //显示extendClass::showMsg baseClass.showMsg.call(instance);//显示baseClass::showMsg static var baseinstance = new baseClass();
baseinstance.showMsg.call(instance);//显示baseClass::showMsg </script>

总结:本文对在javascript中经常出现且难以理解的prototype属性,在含义,使用方法(给prototype添加属性,用prototype给对象添加函数),在添加函数且调用内容函数过程中遇到的一些问题提供了相应的解决方法等方面做了相关的解释,希望对大家有帮助,喜欢的话,记得动动手指点点推荐哦!

js中Prototype属性解释及常用方法的更多相关文章

  1. js的Prototype属性 解释及常用方法

    函数:原型 每一个构造函数都有一个属性叫做原型(prototype,下面都不再翻译,使用其原文).这个属性非常有用:为一个特定类声明通用的变量或者函数. prototype的定义 你不需要显式地声明一 ...

  2. JS中prototype属性-JS原型模式

    /* *对象方法 *类方法 * 原型方法 */ function People(name) { this.name = name; this.say = function () { //对象方法 al ...

  3. 简单理解js的prototype属性

    在进入正文之前,我得先说说我认识js的prototype这个东西的曲折过程. 百度js的prototype的文章,先看看,W3School关于prototype的介绍: 你觉得这概念适合定义js的pr ...

  4. Javascript中prototype属性详解 (存)

    Javascript中prototype属性详解   在典型的面向对象的语言中,如java,都存在类(class)的概念,类就是对象的模板,对象就是类的实例.但是在Javascript语言体系中,是不 ...

  5. (转载)详解Javascript中prototype属性(推荐)

    在典型的面向对象的语言中,如java,都存在类(class)的概念,类就是对象的模板,对象就是类的实例.但是在Javascript语言体系中,是不存在类(Class)的概念的,javascript中不 ...

  6. 复习一下js的prototype 属性

    <html> <head> <meta charset="utf-8"> <title>菜鸟教程(runoob.com)</t ...

  7. Javascript中prototype属性

    prototype作为JS相对比较难理解的一个知识点,在这里发表下自己的理解. 本文将包含以下几部分内容: 1.js prototype的简单介绍, 2.js构造函数的介绍, 3.prototype的 ...

  8. JS中prototype,js原型扩展

    作者:轩脉刃(yjf512)出处:(http://www.cnblogs.com/yjf512/)版权声明:本文的版权归作者与博客园共有.欢迎转载阅读,转载时须注明本文的详细链接. 原文 http:/ ...

  9. js中prototype和constructor的认识

    最初对js中 object.constructor 的认识: 我们都知道,在JS中有一个function的东西.一般人们叫它函数.比如下面的代码 function Person(name)    {  ...

随机推荐

  1. 表单input中录入资料的检查方法及示例

    本文内容 表单录入信息的检查原则 常见检查的三种方法 示例     输入框有字符长度的限制     输入框有输入字符个数范围的限制 知识补给--检查方式的介绍     输入框只可(或不可)输入数 ...

  2. 【SQL】SQL2012离线帮助文档安装不上的处理手记

    注:解决方法在最后,心急的童鞋可以直接往下滚动. 我SQL实例装的是2008 R2版,由于该版自带的SSMS(Microsoft SQL Server Management Studio 管理工具)存 ...

  3. Asp.net Mvc模块化开发系列(目录)

    模块化开发是非常重要的,模块化开发是个系统性问题,为此我觉得有必须要写一个系列的文章才能基本说的清楚 那又为什么要写一个目录呢? 其一.是对我昨天承诺写一个系列新的文章的回应 其二.是先写出一个大纲, ...

  4. 孙鑫MFC学习笔记17:进程间通信

    17 1.进程间通信4种方式 2.OpenClipboard打开剪贴板 3.EmptyClipboard清空剪贴板,并把所有权分配给打开剪贴板的窗口 4.SetClipboardData设置剪贴板数据 ...

  5. Java 读取Properties文件时应注意的路径问题

    1. 使用Class的getResourceAsStream()方法读取Properties文件(资源文件)的路径问题:  InputStream in = this.getClass().getRe ...

  6. 迷信AgainAndAgain

    又重新在VBox中安装Debian其它镜像两次,依然在安装桌面软件包时挂掉...

  7. HDU 1141---Brackets Sequence(区间DP)

    题目链接 http://poj.org/problem?id=1141 Description Let us define a regular brackets sequence in the fol ...

  8. Data Structures/Algorithms 小甲鱼99讲笔记系列(1~~15讲)

    参考资料地址: http://www.icoolxue.com/ 1.数据结构中四种逻辑结构. ① 集合 集合中任何两个数据元素之间都没有逻辑关系,组织形式松散. ② 线性结构 线性结构中的 结点按逻 ...

  9. 利用Canvas编辑图片

    使用<canvas>对象在浏览器中把一幅彩色图片变成灰度图片. grayscale.html <!DOCTYPE html> <html lang="en&qu ...

  10. C语言关键字、标识符和注释

    一.关键字 C语言提供的有特殊含义的符号,共32个. 在Xcode中关键字全部高亮显示,关键字全部都为小写.如return.int等. 二.标识符 定义:标识符是程序员在程序中自定义的一些符号和名称. ...