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这个自定义的对象类型没有封装性可言。

~~可以通过原型模式解决上面的问题。

原文地址:https://www.cnblogs.com/LinSL/p/7289327.html