博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
DOM笔记(十二):又谈原型对象
阅读量:4286 次
发布时间:2019-05-27

本文共 3549 字,大约阅读时间需要 11 分钟。

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

一、理解原型对象

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

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

 

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

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

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

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

 

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

per1.blog = "www.ido321.com";alert(per1.hasOwnProperty("blog"));  //truealert(Person.prototype.hasOwnProperty("blog"));  //falsealert(per1.hasOwnProperty("name"));  //falsealert(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);   //truealert(Object.getPrototypeOf(per1).name);                 //dwqs

 

二、__proto__属性

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

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

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

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

//全是truealert(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);  //truealert(per1 instanceof Person);  //truealert(per1.constructor == Object);  //truealert(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了(参考),即可以枚举,默认情况下,该属性不可枚举。

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

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);              //functionalert(typeof String.prototype.substring);   //function

 

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

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

 

原文首发:
你可能感兴趣的文章
iOS 输出指定位数
查看>>
iOS 中的传值的方法
查看>>
PHP 基础二
查看>>
iOS IPV6域名转IP
查看>>
iOS 解决苹果手机锁屏后APP退出的问题及app状态
查看>>
PHP基础三
查看>>
iOS7以后解决view上移的问题
查看>>
iOS后台运行延长时间
查看>>
PHP基础 四
查看>>
iOS中导航栏navigationBar返回按钮--导航右侧按钮--常用设置、导航控制器全局设置返回按钮
查看>>
iOS中判断是否首次下载app
查看>>
iOS 沙盒机制,沙盒存储,钥匙串
查看>>
iOS设备唯一标识保存、钥匙串
查看>>
iOS判断网络
查看>>
iOS需要学习和解决的若干问题-----------------
查看>>
iOS 十进制转换成十六进制
查看>>
PHP 基础五
查看>>
PHP基础六 数组
查看>>
iOS 判断手机上是否装了某款软件
查看>>
PHP 数据库mysql(一)命令行操作数据库
查看>>