转载

javascript中的模式解析——原型模式

理解原型模式,首先要理解prototyoe(这个单词翻译 原型)属性, 《javascript高级程序设计》 书中描述到——我们创建的每个函数都有一个prototype属性,这个属性是一个指针,指向一个对象,而这个对象的用途是包含可以由特定类型的所有实例共享的属性和方法。

我在上一篇构造函数模式所说的,我们构建了一个一个Person函数,然后通过new一个person函数来创建了person1实例,person2实例,既然每个函数都有一个prototype属性,那么我有几个问题想要弄明白:

  1. person1的prototype属性指向哪个对象?
  2. Person对象也是我们创建的一个函数,它有没有prototype属性,如果有,它的prototype属性又指向哪?

第一个答案,person1的prototype属性指向Person对象 (这个应该能理解吧)

那么第二个问题看起来就有些奇怪,Person对象的prototype的属性指向哪啊?它可以我们自定义的,可不是一个实例。答案是Person对象的prototype属性指向Person对象(如果我没理解错的话)

这听起来是挺别扭的,函数的原型对象是它本身,但是,它的真实构造是这样的:

当我们创建了一个自定义的构造函数(假设为Person)后,自定义构造函数的prototype属性指向原型对象,但是每个原型对象中有一个constructor(翻译 构造函数)属性,这个属性指向我们的自定义函数。说到这里,大家就应该能理解为什么我说Person对象的prototype属性指向它本身。我给大家举个形象生动的例子啊(仅供参考)。Person是一个人,他的左手叫prototype,有一天他想找他的原型对象,他把左手伸出去找啊找啊的,一下抓到一个匹配的原型对象的右手(constructor),他顺着原型对象的右手往上看原型对象的脸,咦,这不是我么?person1有一天也想找原型对象了,他也伸出他的左手(prototype)去找啊找啊,抓到了一个匹配的原型对象的右手,他也顺着原型对象的右手往上看,咦,这不是Person么!

哈哈,希望能逗大家一笑,那么我有一个问题

3.prototype属性有什么用?

function Person() {} Person.prototype.name="guoshiwei"; Person.prototype.age=23; Person.prototype.sayName=function(){ alert(this.name) }; var person1=new Person(); person1.sayname(); //"guoshiwei" var person2 = new Person(); person2.sayName() //"guoshiwei"  alert(person1.sayName == person2.sayName); //true

当我们需要一个所有实例都需要的属性或方法时,可以把它添加到原型对象上,所有实例都能共享这些属性或方法,我们可以看到,person1和person2引用同一个原型对象,换句话说,只要是通过new Person()创建的实例对象,他们都引用同一个原型对象

还有一些问题

Person.prototype.name= "guoshiwei"; Person.prototype.age=23; var person1=new Person(); person1.name="bushiguoshiwei"; alert(person1.name) // "bushiguoshiwei" alert(person1.age) //23 delete person1.name; alert(person1.name); //"guoshiwei"

通过这段代码,我们可以理解对象原型和实例对象是怎样工作的,当我们调用实例中的属性和方法时,我们先看实例对象本身的属性和方法有没有这个属性和方法,如果有,就调用,如果没有,那我们就去这个实例对象的原型对象中找这些属性或者方法,如果有,就调用,如果没有就报错(是报错还是显示undefined啊?我也不太清楚)。如果不清楚这种向上查询的意思,可以去了解一下原型链, 《javascript高级程序设计》 第四章 ,这章挺重要的,原型链还涉及到后面闭包的问题。

不知道大家想过没有,能不能通过实例对象修改原型对象的属性或方法啊?

function Person(){ } var person1= new Person(); person1.prototype.name = "guoshiwei"; var person2= new Person(); alert(person2.name); //报错,person1.prototype is undefined(火狐)

是不是实例对象只能引用原型对象,而只有构造函数可以添加或删除(能删除吗?)  或者说原型对象中的constructor属性指向谁谁才能操作原型对象?

总的来说:构造函数模式可以创建可以标识的实例,并且实例可以具有构造函数中的属性或方法,而原型模式可以把需要共享的属性或者方法添加到原型对象中,减少了实例中的方法的重复创建,所以,构造函数模式和原型模式混合使用时目前最常用的方法!

正文到此结束
Loading...