说一说JavaScript 中的原型ProtoType

     一时兴起,写一遍博客吧。

    

     “函数是函数,函数也是对象” 相信学过js 的同学看到这句话很熟悉。我表示耳朵都听出茧子了。 

   我们都知道,在JavaScript中是没有类的概念的,那么怎么来new 一个对象呢?首先,来看一下我们写一个普通的 构造函数。

 1 function Person(name, age, gender) {
 2             this.user_name = name;
 3             this.user_age = age;
 4             this.user_gender = gender;
 5 
 6             this.sayHi = function () {
 7                 alert("我叫"+this.user_name+",我年芳"+this.user_age+"我是一个分流倜傥的"+this.user_age+"生");
 8             }
 9         }
10 
11         //创建两个对象;
12         var p1 = new Person('李寻欢', 18, '男');
13         p1.sayHi();
14 
15         var p2 = new Person('张无忌', 20, '男');
16         p2.sayHi();


很好 代码像我们想象的原样输出了。谁打印谁的互不相干。

   从上面的代码我们可以看出来, p1 跟p2 之间是没有任何联系的,这很像C#里面的对象,每个对象保存自己的属性。这是js的优点。 

但是,其中有 一个匿名函数赋值给了 sayHi ,匿名函数也是对象,我们都知道 对象是占内存的然而 这就变成了一个缺点。 因为当我们new 500个对象的时候,在内存中就会有500个sayHi 这是没必要的,因为都是那个函数,而属性是必须每个对象都要有自己的一份的。

   如果你们说,属性都是自己独一份,你怎么知道他们调用的不是一个方法呢?  你可以打开编辑器试着改改代码吗? 我很懒的。

1         p1.user_name = '花无缺';
2         p1.user_age = '19';
3         p1.user_gender = '男';
4 
5         p1.sayHi = null;   // 把p1的函数赋值 为null;
6 
7         p1.sayHi(); // F12 一下 报错了
8         p2.sayHi(); //原样输出、

这下你们信了吧

    那么怎么解决这个问题呢?  就要用到了 ProtoType了。

   我们把函数放到prototype原型对象里面去,调用的时候都从原型对象里面调用。

 OK啊 这样就解决了。那么怎么写代码呢?

 1         function Person(name, age, gender) {
 2             this.user_name = name;
 3             this.user_age = age;
 4             this.user_gender = gender;
 5 
 6         }
 7         Person.prototype.sayHi = function () {
 8             alert("我叫" + this.user_name + ",我年芳" + this.user_age + "我是一个分流倜傥的" + this.user_gender + "生");
 9         }
10 
11         //创建两个对象;
12         var p1 = new Person('李寻欢', 18, '男');
13         p1.sayHi();
14 
15         var p2 = new Person('张无忌', 20, '男');
16         p2.sayHi();

   嗨呀!皮呦 怎么回事,我把 sayHi的函数给了 prototype 这个原型对象怎么跟p1 p2 关联起来的? 

   先说一下你们认为 user_name,user_age....等等属性是谁的? 是Person函数对象的?通过Person创建的p1 p2中能点出来 prototype? 

完全不是,user_name,user_age 属性是创建的对象的而不是Person的。prototype是函数对象才有的 ,普通对象是没有的。

  举个例子: 就像一个妈妈肚子里怀着一个宝宝,宝宝头嘴角有颗美人痣,那么这个痣是宝宝自己的,不是他妈妈的。

具体到代码里面就是 Person.constructor 有个这个构造函数,当创建对象的时候,内部调用构造函数执行 user_age user_name ..这个段代码,p1 p2 里面才会有。

 先看下面这幅图,我再具体说一下;

 

  在创建的每一个对象中,都有一个 __proto__ 这么一个属性,在我们使用p1.sayHi的时候他会首先在自己里面找这个方法,找不到就会通过__proto__这个属性找到原型对象,

去调用原型对象里面的方法。 如果在原型对象里面没找到的话,没关系,原型对象中也有一个__proto__属性,相信大家也猜到了 ,这是不是非常像C#中的继承?

对的。 js是通过原型对象来实现继承的。

   

  总算写完了。

 

    转载请说明出处

 

posted @ 2017-12-07 21:03  liyanzhao  阅读(199)  评论(0编辑  收藏  举报