美文网首页
2018-11-24

2018-11-24

作者: kathyever | 来源:发表于2018-11-24 12:00 被阅读0次

6.2.3 原型模式

我们创建的 每个函数都有一个prototype(原型)属性。
这个属性是一个指针,指向一个对象,而这个对象的用途是包含可以由特定类型的所有实例共享的属性和方法。
prototype()就是通过调用构造函数而创建的那个对象实例的原型对象。
使用原型对象的好处是不必在构造函数中定义对象实例的信息,而是可以将这些信息直接添加到原型对象中,例:

function Person(){
}
Person.prototype.name="kathy";
Person.prototype.age=18;
Person.prototype.job="student";
Person.prototype.sayName=function(){
    alert(this.name);
};
var person1=new Person();
person1.sayName();//kathy

var person2=new Person();
person2.sayName();//kathy

alert(person1.sayName == person2.sayName);//true

1、理解原型对象
无论什么时候,只要创建了一个新函数,就会根据一组特定的规则为该函数创建一个prototype属性,这个属性指向函数的原型对象。
在默认情况下,所有原型对象都会自动获得一个constructor(构造函数)属性,这个属性包含一个指向prototype属性所在函数的指针。

创建了自定义的构造函数之后,其原型对象默认只会取得constructor;而其他方法都是从Object继承而来的。

image.png

上图中展示了Person构造函数、Person的原型属性以及Person现有的两个实例质检的关系。虽然person1和person2都指向了Person.prototype,但是它们与构造函数没有直接的关系。
特别要注意的事,这两个实例虽然都不包含属性和方法,但是却可以调用person1.sayName()。这是通过查找对象属性的过程实现的。

ECMAScript5增加了一个新方法:Object。getPrototype(),返回[[Prototype]]的值:

alert(Object.getPrototypeof(person1) == Person.prototype);//true
//确定Object.getPrototypeof( )返回的对象实际上就是这个对象的原型
alert(Object.getPrototypeof(person1).name);//kathy
//取得原型对象中name属性的值,也就是kathy

使用Object.getPrototypeof( )可以方便的取得一个对象的原型

每当代码读取某个对象的某个属性时,都会执行一次搜索,目标是具有给定名字的属性。搜索首先从对象实例本身开始。如果再实例中找到了具有给定名字的属性,则返回该属性的值;如果没有找到就继续搜索指针指向的原型对象,在原型对象中查找具有给定名字的属性。
如果再原型对象中找到这个属性,则返回该属性的值。

可以通过对象实例访问保存在原型中的值,但是不能通过对象实例重写原型中的 值。

function Person(){
}
Person.prototype.name="kathy";
Person.prototype.age=29;
Person.prototype.job="student";
Person.prototype.sayName=function(){
    alert(this.name);
};
var person1=new Person();
var person2=new Person();

person1.name="stephen";
alert(person1.name);//stephen——来自实例
alert(person2.name);//kathy——来自原型

当为对象实例添加一个属性的时候,这个属性会阻止我们访问原型中的那个属性,但是不会修改那个属性。
即使这个属性设置为null,也会在这个实力中设置这个属性,而不会回复其指向原型的链接。
不过,如果使用delete操作符则可以完全删除实例属性,使我们可以重新访问原型中的属性。

function Person(){
}
Person.prototype.name="kathy";
Person.prototype.age=29;
Person.prototype.job="student";
Person.prototype.sayName=function(){
    alert(this.name);
};
var person1=new Person();
var person2=new Person();

person1.name="stephen";
alert(person1.name);//stephen——来自实例
alert(person2.name);//kathy——来自原型

delete person1.name;
alert(person1.name);//kathy

使用hasOwnProperty( )方法可以检测一个属性是存在于实例中,还是存在于原型中。这个方法(不要忘了它是从Object继承来的)只在给定属性存在于对象实例中时,才会返回true。例:

function Person(){
}
Person.prototype.name="kathy";
Person.prototype.age=29;
Person.prototype.job="student";
Person.prototype.sayName=function(){
    alert(this.name);
};
var person1=new Person();
var person2=new Person();

alert(person1.hasOwnProperty("name"));

person1.name="stephen";
alert(person1.name);//stephen——来自实例
alert(person1.hasOwnProperty("name"));//true

alert(person2.name);//kathy——来自原型
alert(person2.hasOwnProperty("name"));

delete person1.name;
alert(person1.name);//kathy——来自原型
alert(person1.hasOwnProperty("name"));//false

2、原型与in操作符

有两种方式使用in操作符:单独使用和在for-in循环中使用。
在单独使用时,in操作符会在通过对象能够访问给定属性时返回true,无论该属性存在于实例中还是原型中,例:

function person(){
}
Person.prototype.name="kathy";
Person.prototype.age=18;
Person.prototype.job="student";
Person.prototype.sayName=function(){
    alert(this.name);
};

var person1=new Person();
var person2=new Person();

alert(person1.hasOwnProperty("name"));//false
alert("name" in person1);//true

person1.name="stephen";
alert(person1.name);//stephen——来自实例
alert(person1.hasOwnProperty("name"));//true
alert("name" in person1);//true

alert(person2.name);//kathy——来自原型
alert(person2.hasOwnProperty("name"));//false
alert("name" in person2);//true

delete person1.name;
alert(person1.name);//kathy——来自原型
alert(person1.hasOwnProperty("name"));//false
alert("name" in person1);//true

function person(){
}
Person.prototype.name="kathy";
Person.prototype.age=18;
Person.prototype.job="student";
Person.prototype.sayName=function(){
    alert(this.name);
};
var person= new Person();
alert(hasPrototypeProperty(person,"name"));

person.name= "stephen";
alert(hasPrototypeProperty(person,"name"));

相关文章

网友评论

      本文标题:2018-11-24

      本文链接:https://www.haomeiwen.com/subject/bqueqqtx.html