js设计模式之路--原型对象

第一想法

创建一个人类,然后为其添加属性和方法,我最直接的想法:

 1 function Person(name, age) {
 2     this.name = name;
 3     this.age = age;
 4     this.sayName = function() {
 5         alert("xxx");
 6     }
 7 }
 8 
 9 var p1 = new Person('z3', 20);
10 var p2 = new Person('z4', 18);
11 
12 console.log(p1.sayName == p2.sayName);

测试结果: false 

说明:

    因为我们通过类实例化对象的时候,相当于复制了类中的共有属性和共有方法,创建了一个新的对象。每次通过new实例化的对象,都是独立的。因此我们打印p1.sayName和p2.sayName结果为false。

 

同时我们也发现类中sayName方法,是不变化的,即使alert也是打印的“xxx”。与name和age相比,name和age是接手实例化对象的时候,传入的参数,而sayName是不接收任何的,而且函数内容也是固定的。

这个固定的如果我们没次实例化的时候都创建一份的话,如果实例化对象的数量多的话,会导致资源浪费。像这种固定不变的,我们应该将其提出来,单独放在一个地方,需要的时候直接去拿来用就可以。不用在每个对象中都去实例化。

提出不变方法一

第一种处理办法是直接将方法提出来,然后在类中将这个方法的引用赋值给这个方法。

 1 function sayName = function() {
 2     alert("xxx");
 3 }
 4 
 5 function Person(name, age) {
 6     this.name = name;
 7     this.age = age;
 8     this.sayName = sayName;
 9 }
10 
11 var p1 = new Person('z3', 20);
12 var p2 = new Person('z4', 18);
13 
14 console.log(p1.sayName == p2.sayName);
将不变方法提出来

测试结果: true 

说明:

通过结果我们看出,此时类中的sayName方法是同一个。这样我们不用重复创建不变的内容。只是将其放在哪里,然后要用直接去拿就可以。

 

但是这样我们将这个方法提出来是有问题的。这样操作,提出来的方法,作用在全局变了上。意思就是所有的方法都可以调用。而我们这个方法本身我们定义的时候就是为Person这个类服务的。别的类是不能拿去使用的。按现在这样定义的是处理不来这个方法的。这样容易造成全局变量污染。

绑定在原型上

prototype:创建每个对象的时候都有一个prototype属性,这是一个指针总是指向一个对象。而指向的这个对象的用途就是将特定不变的属性和方法包含在内,而可以被所有的实例对象所共有。

 1 function Person(name, age) {
 2     
 3 }
 4 
 5 var obj = Person.prototype;
 6 obj.name = 'z3';
 7 obj.age = 20;
 8 
 9 var p1 = new Person();
10 
11 console.log(p1.name);

结果: z3 

注意:

    我们将name和age属性绑定在prototype上。这样所有通过new Person实例化的对象,也可以通过原型访问这些属性,但是有一点,我们也看到,这些属性绑定在原型上,赋的值都是固定的“z3”和20。因此印证了上面说的用途,就是将特定不变的属性和方法绑定在原型对象上。

此时我们对实例个对象,测试他们能否访问,访问的属相书否相等?

 1 function Person(name, age) {
 2     
 3 }
 4 
 5 var obj = Person.prototype;
 6 obj.name = 'z3';
 7 obj.age = 20;
 8 
 9 var p1 = new Person();
10 var p2 = new Person();
11 
12 console.log(p1.name);
13 console.log(p2.name);
14 console.log(p1.name == p2.name);

结果:

z3
z3
true

constructor

每个实例化的对象都有constructor属性,都执行对象的构造函数的。理清下思路:

  • 1、构造函数.prototype = 原型对象
  • 2、原型对象.constructor = 构造函数
  • 3、实例对象的prototype = 原型对象 = 构造函数.prototype

注意:

这里检测第三点的时候,不能直接console.log()或者使用alert();来打印,如果打印的话结果也是 undefined。只能使用 isPrototytpeOf 来进行检测。

1 console.log(obj.isProtypeOf(p1));

结果;  true 

 

原型图例:

 

posted on 2017-07-25 17:28  jayafs  阅读(79)  评论(0)    收藏  举报

导航