因为之前谢过一篇关于原型对象的笔记:浅谈JavaScript中的原型模式。现在我又重新看到这个话题,对原型有了进一步的理解,所以,又要谈谈原型对象。

一、理解原型对象

创建的每一个函数都有一个prototype属性,它指向这个函数的原型对象。利用原型模式创建的方法和属性是被所有实例所共享的。

function Person(){}
Person.prototype.name="dwqs";
Person.prototype.age=20;
Person.prototype.sayName=function()
{
alert(this.name);
};
var per1 = new Person();
per1.sayName(); //dwqs
var per2 = new Person();
per2.sayName(); //dwqs
alert(per1.sayName == per2.sayName); //true

默认情况下,prototype指向的原型对象自动获取一个constructor属性,指向prototype属性所在的函数,而原型对象的其它方法和属性均从Object继承。

当调用Person的构造函数创建对象per1和per2时,Person的每个实例(per1和per2)均包含一个指向构造函数(Person)的原型对象的指针。ECMA-262第5版给指针取名为[[Prototype]]。

所以,实例中的指针仅指向原型,而不指向构造函数。虽然没有标准的方法直接访问[[Prototype]]特性,但在DOM笔记(十一)中提供了hasOwnProperty()和isPropertyOf()方法来反应原型对象和实例之间的关系。

//isPrototypeOf(obj)检测obj的[[prototype]]是否指向调用此方法的对象
alert(Person.prototype.isPrototypeOf(per1)); //true
alert(Person.prototype.isPrototypeOf(per2)); //true

hasOwnProperty()则是判断属性是存在原型中还是实例中,只有存在实例中时,才返回true。

per1.blog = "www.ido321.com";
alert(per1.hasOwnProperty("blog")); //true
alert(Person.prototype.hasOwnProperty("blog")); //false
alert(per1.hasOwnProperty("name")); //false
alert(Person.prototype.hasOwnProperty("name")); //true

若实例属性和原型属性同名,则同名的原型属性会被屏蔽,但是不会修改原型中的同名属性,当删除同名的实例属性后,又能重新访问被屏蔽的原型属性。

per1.name="i94web";
alert(per1.name); //i94web,来自实例
alert(per2.name); //dwqs 来自原型
delete per1.name;
alert(per1.name); //dwqs

ECMAScript 5提供了Object.getPrototypeOf(obj)来访问obj的[[Prototype]]的指向,即返回obj的原型对象

alert(Object.getPrototypeOf(per1) == Person.prototype);   //true
alert(Object.getPrototypeOf(per1).name);                 //dwqs

二、__proto__属性

在IE11、FireFox、Google等现代浏览器中,每个对象支持__proto__(前后都是两个下划线)属性用于访问父类的原型对象。但要注意的是:

1、原型对象应用__proto__属性时,返回当前类的父类的原型对象的引用;当实例对象应用__proto__属性时,返回当前实例所属类的原型对象的引用。

2、Object.prototype.__proto__返回null,Object没有父类。

3、prototype是静态属性,__proto__是实例属性。

//全是true
alert(Array.prototype.__proto__ == Object.prototype);
alert((new Array()).__proto__ == Array.prototype);
alert(Person.prototype.__proto__ == Object.prototype);
alert(per1.__proto__ == Person.prototype);
alert(Object.prototype.__proto__ == null);

三、重写原型

如果在原型上定义属性或者方法,每次都要将Person.prototype敲一遍,很麻烦。一个简单的方法就是重写原型。

function Person(){}
Person.prototype={
name:"dwqs",
age:20,
sayName:function()
{
alert(this.name);
}
};
var per1 = new Person();
alert(per1 instanceof Object); //true
alert(per1 instanceof Person); //true
alert(per1.constructor == Object); //true
alert(per1.constructor == Person); //false

因为重写了默认的prototype对象,所以constructor属性指向了新对象的constructor属性(Object构造函数),而不是指向Person了。如果constructor指向很重要,可以重新定义:

function Person(){}
Person.prototype={
constructor:Person, //重新定义constructor
name:"dwqs",
age:20,
sayName:function()
{
alert(this.name);
}
};
var per1 = new Person();
alert(per1.constructor == Person); //true

这样设置之后,constructor的特性[[Enumerable]]是true了(参考DOM笔记(十一)),即可以枚举,默认情况下,该属性不可枚举。

正如前文说的,实例中的指针仅指向原型,而不指向构造函数。所以重写原型对象之后,会切断现有原型和任何之前已经存在的对象实例之间的联系。

function Person(){}

//先创建一个实例
var per1 = new Person(); //重写原型
Person.prototype={
constructor:Person,
name:“dwqs”,
age:20,
sayName:function()
{
alert(this.name);
}
};
per1.sayName(); //错误:Uncaught TypeError: undefined is not a function

重写原型对象之前是这样的:

重写原型对象变成这样了:

四、原生对象的原型

所有原生引用类型,如Object、Array、String等都在其构造函数的原型上定义了方法。在Array.prototype上可以找到sort(),在String.prototype上可以找到substring

alert(typeof Array.prototype.sort);              //function
alert(typeof String.prototype.substring); //function

因此,也可以在原型对象上为引用类型定义新的方法

String.prototype.startWith=function(str)
{
return this.indexOf(str) == 0;
}
var msg = "Hello world";
alert(msg.startWith("Hello")); //true

原文首发:http://www.ido321.com/1372.html

DOM笔记(十二):又谈原型对象的更多相关文章

  1. python cookbook第三版学习笔记十二:类和对象(三)创建新的类或实例属性

    先介绍几个类中的应用__getattr__,__setattr__,__get__,__set__,__getattribute__,. __getattr__:当在类中找不到attribute的时候 ...

  2. 《C++游戏开发》笔记十二 战争迷雾:初步实现

    本系列文章由七十一雾央编写,转载请注明出处.  http://blog.csdn.net/u011371356/article/details/9475979 作者:七十一雾央 新浪微博:http:/ ...

  3. python3.4学习笔记(十二) python正则表达式的使用,使用pyspider匹配输出带.html结尾的URL

    python3.4学习笔记(十二) python正则表达式的使用,使用pyspider匹配输出带.html结尾的URL实战例子:使用pyspider匹配输出带.html结尾的URL:@config(a ...

  4. Go语言学习笔记十二: 范围(Range)

    Go语言学习笔记十二: 范围(Range) rang这个关键字主要用来遍历数组,切片,通道或Map.在数组和切片中返回索引值,在Map中返回key. 这个特别像python的方式.不过写法上比较怪异使 ...

  5. DirectX11笔记(十二)--Direct3D渲染8--EFFECTS

    原文:DirectX11笔记(十二)--Direct3D渲染8--EFFECTS 版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/u010333737 ...

  6. java jvm学习笔记十二(访问控制器的栈校验机制)

    欢迎装载请说明出处:http://blog.csdn.net/yfqnihao 本节源码:http://download.csdn.net/detail/yfqnihao/4863854 这一节,我们 ...

  7. DOM笔记(十一):JavaScript对象的基本认识和创建

    一.什么是对象? 面 向对象(Object-Oriented,OO)的语言有一个标志,那就是都有类的概念,例如C++.Java等:但是ECMAScript没有类的概 念.ECMAScript-262把 ...

  8. JavaScript权威设计--命名空间,函数,闭包(简要学习笔记十二)

    1.作为命名空间的函数 有时候我们需要声明很多变量.这样的变量会污染全局变量并且可能与别人声明的变量产生冲突. 这时.解决办法是将代码放入一个函数中,然后调用这个函数.这样全局变量就变成了 局部变量. ...

  9. DOM笔记(二):Node接口

    所有的节点都使用Node接口来表示,可以使用很多方法去获取节点,如document.getElementsByTagName().document.getElementsByName()等均返回一个N ...

随机推荐

  1. 表格排序插件datatables

    之前用过表格排序插件tinytables,用到后面,随着需求的更改,发现这个插件真的low到爆了,不适合用于多表格,只有一个表格的页面可以凑合着用,有很多局限性. 之后发现了一款表格排序插件datat ...

  2. Go语言构建json和解析json实例

    参考网址如下: https://www.cnblogs.com/fengbohello/p/4665883.html

  3. idea导入servlet项目

    转载:https://www.cnblogs.com/qiyebao/p/6236012.html

  4. my.助战选择

    ZC:我的选项:铁扇.小白龙.北海龙女.北海龙子(涌浪).老鼠精(避敌锋芒).惠岸.银角 ZC:我的选择(日常速推不是我急需的,慢一点无所谓,我需要过难度):老鼠精(避敌锋芒).银角(首回合隐身,每回 ...

  5. 基于MVC模式开发的后台框架

    1.ThinkCMF 2.NFine快速开发平台 3.力软快速开发框架 如有好的开发框架希望可以一起交流

  6. 夜神模拟器连不上adb的解决办法

    解决办法: 1.任务管理器里看下,adb.exe以及nox_adb.exe这2个进程有没有在运行?有的话就结束掉 2.找到开发环境的SDK的目录和夜神模拟器的目录,将SDK\platform-tool ...

  7. 性能测试工具Jmeter06-Jmeter元件作用域和执行顺序

    元件作用域 8类可被执行的元件(测试计划与线程组不属于可执行元件),这些元件中,取样器(sampler)是典型的不与其它元件发生交互作用的元件,逻辑控制器只对其子节点的取样器有效,而其它元件(配置元件 ...

  8. Emacs学习笔记1

    Emacs笔记-Emacs基本的文本操作 使用命令时要在minibuffer缓冲区中 关于文件 注意 在对单词的操作中C开头的控制范围要比M开头的控制范围要下 对于文件的撤销操作, 不要使用C-x, ...

  9. 【AngularJs】---angular-chart.js 图表报表

    移步至我在百度经验的这篇文章: http://jingyan.baidu.com/article/a378c960b26636b3282830ad.html

  10. .net 与 asp.net

    .net 指的是框架,框架包含很多东西例如: > 语言: VB, C#, C++, Ruby, Python ... > 类库: 网络通讯,图像处理, 安全,IO,数据链接访问 ... & ...