Understand the prototype prototype object of js

Of the articles I've read about prototypes, this one is the best! everyone enjoy

Every function we create has a prototype property, which is a pointer to an object whose purpose is to contain properties and methods that can be shared by all instances of a particular type. If taken literally, prototype is the prototype object of the object instance created by calling the constructor. The advantage of using a primitive object is that all object instances can share the properties and methods it contains. In other words, rather than having to define information about an object instance in the constructor, this information can be added directly to the prototype object, as shown in the following example.

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
function Person(){}
Person.prototype.name = 'mychirs' ;
Person.prototype.age = 29 ;
Person.prototype.job = 'Software Engineer' ;
Person.prototype.sayName = function(){
   alert( this .name);
};
 
var person1 = new  Person();
person1.sayName(); //'mychirs'
 
var person2 = new  Person();
person2.sayName(); //'mychirs'
 
alert(person1.sayName == person2.sayName); //true

 

 

Here, we add the sayName() method and all properties directly to the Person's prototype property, and the constructor becomes an empty function. Even so, a new object can still be created by calling the constructor, and the new object will have the same properties and methods. But unlike the constructor pattern, these properties and methods of the new object are shared by all instances. in other words. Both personl and person2 access the same set of properties and the same sayName() function. To understand the working principle of the prototype pattern, you must first understand the properties of ECMAScript prototype objects.

 

Understanding prototype objects


无论什么时候,只要创建了一个新函数,就会根据一组特定的规则为该函数创建一个prototype属性,这个属性指向函数的原型对象。在默认情况下,所有原型对象都会自动获得一个constructor(构造函数)属性,这个属性包含一个指向prot otype属性所在函数的指针。就拿前面的例子来说,Person.prototype. constructor措向Person。而通过这个构造函数,我们还可继续为原型对象添加其他属性和方法。
创建了自定义的构造函数之后,其原型对象默认只会取得constructor属性;至于其他方法,则都是从Obj ect继承而来的。当调用构造函数创建一个新实例后,该实例的内部将包含—个指针(内部属性),指向构造函数的原型对象。ECMA-262第5版中管这个指针叫[[Prototype】]。虽然在脚本中没有标准的方式访问【[ Prototype]],但Firefox、Safari和Chrome在每个对象上都支持一个属性—proto_;而在其他实现中,这个属性对脚本则是完全不可见的。不过,要明确的真正重要的一点就是,这个连接存在于实例与构造函数的原型对象之间,而不是存在于实例与构造函数之间。
以前面使用Person构造函数和Person.prototype创建实例的代码为例,图6-1展示了各个对象之间的关系。

\

 

 

 

上图展示rr Person构造函数、Person的原型属性以及Person现有的两个实例之间的关系。在此,Person *prototype指向了原型对象,而Person.prototype.constructor叉指回了Person。原型对象中除了包含cons t,ruct or属性之外,还包括后来添加的其他属性。Person的每个实例personl和person2都包含一个内部属性,该属性仅仅指向了Person.prot otype;换句话说,它们与构造函数没有直接的关系。此外,要格外注意的是,虽然这两个实例都不包含属性和方法,但我们却加载中...可以调用personl.sayName()。这是通过查找对象属性的过程来实现的。
虽然在所有实现中都无法访问到[[Prototype]:,但可以通过isProcotypeOf()方法来确定对象之间是否存在这种关系。从本质上讲,如果[[ Prototype]]指向调用isPrototypeOf()方法的对象[Person.prototype).那么这个方法就返回true,如下所示:

 

 
1
2
alert(Person.prototype.isPrototypeOf(personl)); //true
alert(Person.prototype.isPrototypeOf(person2)); //true


这里,我们用原型对象的isPrototypeOf()方法测试了personl和person2 0因为它们内部都有一个指向Person.prototype的指针,因此都返回了true。

 

ECMAScript 5增加了一个新方法,叫Object.getPrototypeOf(),在所有支持的实现中,这个方法返回[[PrototypeJ]]的值。例如:

 

1
2
alert(Object.get PrototypeOf(personl) == Person.prototype); //true
alert(Object.get PrototypeOf(personl).name );   //'Nicholas'

 

 

这里的第一行代码只是确定Object.getPrototypeOf()返回的对象实际就是这个对象的原型。第二行代码取得了原型对象中name属性的值,也就是'Nicholas'。使用Object.getPrototypeOf()可以方便地取得一个对象的原型,而这在利用原型实现继承(本章稍后会讨论)的情况下是非常重要的。支持这个方法的浏览器有IE9+、Firefox 3.5+、Safari 5+、Opera 12+和Chrome。

每当代码读取某个对象的某个属性时,都会执行一次搜索,目标是具有给定名字的属性。搜索首先从对象实例本身开始。如果在实例中找到了具有给定名字的属性,则返回该属性的值;如果没有找到,则继续搜索指针指向的原型对象,在原型对象中查找具有给定名字的属性。如果在原型对象中找到了这个属性,则返回该属性的值。也就是说,在我们调用personl. sayName《)的时候,会先后执行两次搜索。首先,解析器会同:“实例personl有sayName属性吗?”答:“没有。”然后,它继续搜索,再问:“personl的原捌有sayName属性吗?”答:“有。”于是,它就读取那个保存在原型对象中的函数。当我们调用person2.sayName()时,将会重现相同的搜索过程,得到相同的结果。而这正是多个对象实例共享原型所保存的属性和方法的基本原理。

转自 :http://www.cnblogs.com/mfc-itblog/p/5736785.html

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=326526257&siteId=291194637