JS_高程6.面向对象的程序设计(2)创建对象_3 构造函数存在的问题
# 上次讲到用构造函数的模式来创建对象,相对于工厂模式,解决可对象识别的问题。
1 function Person(name,age,job){ 2 this.name=name; 3 this.age=age; 4 this.job=job; 5 this.sayname=function(){ 6 console.log(this.name); 7 } 8 } 9 10 var person1=new Person("xiaoming",12,"Doctor"); 11 person1.sayname();//xiaoming
# 如上,是使用构造函数模式创建对象的形式。使用构造函数的主要问题是,每个方法都要在每个实例上重新创建一次。其实质可以效果等同于以下形式:
1 function Person(name,age,job){ 2 this.name=name; 3 this.age=age; 4 this.job=job; 5 this.sayname=new Function("console.log(this.name)"); 6 } 7 8 var person1=new Person("xiaoming1",12,"Doctor"); 9 var person2=new Person("xiaoming2",12,"Doctor"); 10 person1.sayname();//xiaoming1 11 person2.sayname();//xiaoming2
# 从以上代码看,虽然 person1和person2都有一个sayname方法,但是其实两个是不同的Function实例。如下:
1 console.log(person1.sayname==person2.sayname);//false
# 这样,当我们创建很多实例对象时,相当于同时创建了很多完成同样的任务的不同的sayname()方法,显然不是很好!
# 尝试着把函数定义转移到构造函数外部,如下:
1 function Person(name,age,job){ 2 this.name=name; 3 this.age=age; 4 this.job=job; 5 this.sayname=sayname; 6 } 7 function sayname(){ 8 console.log(this.name); 9 } 10 var person1=new Person("xiaoming1",12,"Doctor"); 11 var person2=new Person("xiaoming2",12,"Doctor"); 12 person1.sayname();//xiaoming1 13 person2.sayname();//xiaoming2 14 15 console.log(person1.sayname==person2.sayname);//true
# 如上,这样写话就解决了多个函数完成同样的功能的问题,person1和person2实际上共享了全局作用域中的sayname函数。
# 但是这里存在以下问题:
(1)在全局作用域中定义的sayname函数实际上只是被Person对象调用,这样让全局作用域有点名不副实。
(2)如果对象中需要定义很多方法,意味着需要定义很多全局函数。
(3)Person这个自定义的对象类型没有封装性可言。
~~可以通过原型模式解决上面的问题。