欢迎光临
我的个人博客网站

动态原型模式


动态原型模式

​ 以构造函数模式组合原型模式在目前看来已经很完美了,硬要挑出它的缺点的话就是封装性差了点,动态原型模式正是致力于解决这个问题的一个方案:

function Person(name, age, sex){ 	this.name = name 	this.age = age 	this.sex = sex 	Person.prototype.sleep = function(){ 		alert(this.name + '睡觉了') 	} } 

​ 将修改原型属性的代码一块写进构造函数里面。但是上面的代码还有一个问题,如果每创建出一个实例,那么就会为 Person.prototype.sleep 重新赋值,这是完全没有必要的,因此下面对此做出了一点修改:

function Person(name, age, sex){ 	this.name = name 	this.age = age 	this.sex = sex 	if (typeof this.sleep !== 'function'){ 		Person.prototype.sleep = function(){ 			alert(this.name + '睡觉了') 		} 	} } 

typeof this.sleep !== ‘function’ 这句判断只会在第一次创建实例的时候为真。由于在创建第一次实例我们就为它的原型对象的属性 sleep 赋值了一个方法,所以在第二次创建新的实例的时候,这个 sleep 的类型自然为 function,判断也就不成立,也就不会再次为原型对象重复无意义的赋值操作。

​ 那么能否再次简化代码,在内部使用字面量的方法重写 Person 的原型呢?

function Person(name, age, sex) { 	this.name = name 	this.age = age 	this.sex = sex 	if (typeof this.sleep !== 'function') { 		Person.prototype = { 			constructor: this, 			sleep: function() { 				alert(this.name + '睡觉了') 			} 		} 	} } 

​ 上面的代码看似没什么问题,实则有个致命的错误:

const person1 = new Person('小明', 22, '男') const person2 = new Person('小红', 22, '女') console.log(person1.sleep)		// undefined console.log(person2.sleep)		// f() 

​ 因为在第一次创建实例的时候,内部的 if 语句在进行它的第一次判断时,第一次创建的实例的原始的原型对象(在创建Person时自动创建的原型对象)就已经存在,所以 person1 内部的原型对象的指针指向的原型对象仍旧是原始的原型对象,在第二次创建出实例 person2 的时候,它的原型指针指向的才是 if 语句中我们重写的新的原型对象。这也就造成了在 person1 访问不到原型对象的属性 sleep,而 person2 却能够正常访问到属性 sleep

赞(0) 打赏
未经允许不得转载:张拓的天空 » 动态原型模式
分享到: 更多 (0)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址

专业的IT技术经验分享 更专业 更方便

联系我们本站主机

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏