JavaScript面向对象编程指南(五) 原型

第5章 原型

5.1 原型属性

        function f(a,b){
            return a*b;
        };
        // length  属性
        f.length;  //2
        // constructor 构造属性
        f.constructor; // function Function() { [native code] }
        // prototype 属性 初始值是空对象
        typeof f.prototype; //"object"

5.1.1 利用原型添加方法和属性

        function f1(name,color){
          // 使用this添加属性
           this.name=name;
           this.color=color;
           this.whatAreYou=function(){
            return 'I am a'+this.color+''+this.name;
           };
        }
        // 使用prototype属性添加属性和方法
        f1.prototype.price=100;
        f1.prototype.rating=3;
        f1.prototype.getInfo=function (){
          return 'Rating: '+this.rating+',price: '+this.price;
        };

5.1.2 使用原型的属性和方法

        function f1(name,color){
          // 使用this添加属性
           this.name=name;
           this.color=color;
           this.whatAreYou=function(){
            return 'I am a'+this.color+''+this.name;
           };
        }
        // 使用prototype属性添加属性和方法
        f1.prototype.price=100;
        f1.prototype.rating=3;
        f1.prototype.getInfo=function (){
          return 'Rating: '+this.rating+',price: '+this.price;
        };
       var f2=new f1('webcam','black');
       f2.color; // "black"
       f2.getInfo(); //"Rating: 3,price: 100"
       // 修改prototype属性,由同一构造器创建的所有对象的prototype属性也都会同时发生改变(会影响在修改之前已经创建的对象)
       f1.prototype.get=function(what){
        return this[what];
       }
       f2.get('price');  // 100

5.1.4 利用自身属性重写原型属性

对象自身属性的优先级高于原型属性

       function F1(name){
        this.name=name;
       };
       F1.prototype.name='Alen';
       var f2=new F1('XiaoMing');
       f2.name;  // "XiaoMing"  不是 Alen
       // 使用hasOwnProperty()判断一个属性是自身属性还是原型属性
       f2.hasOwnProperty('name');  //true
       //删除自身属性后,原型属性才会显示
       delete f2.name; // true
        f2.name; // "Alen"

5.1.5 isPrototypeOf()方法

isPrototypeOf():当前对象是否为另一个对象的原型

        var person={
            like:'eat',
            age:12,
            sex:'boy'
        };
        function F1(name){
             this.name=name;
        }
        F1.prototype=person;
        var f2=new F1('Alen');
        // 判断person是否为f2的原型
       person.isPrototypeOf(f2);  //true
       //使用getPrototypeOf()获取原型
       Object.getPrototypeOf(f2)===person; //true

5.1.6 神秘的__proto__链接

5.2 扩展内建对象

 内建对象的构造器函数可以通过其原型来进行扩展。

 1     <script type="text/javascript">
 2       // 示例1:扩展Array的内建函数,用来查询数组中是否存在某个特定的值
 3       Array.prototype.inArray=function(needle){
 4         for (var i = 0; i < this.length; i++) {
 5             if(this[i]===needle){
 6                return true;
 7             }else{
 8                 return false;
 9             }
10         };
11       };
12       var colors=['red','black','blue'];
13       colors.inArray('red');  //true
14       colors.inArray('green'); //false
15     //示例2:反转字符串
16     // 先利用split()将目标字符串转换成数组,然后调用该数组的reverse()方法产生一个反向数组。
// 最后通过join()方法将结果数组转换为字符串
17 String.prototype.reverse=function (){ 18 return Array.prototype.reverse.apply(this.split('')).join(''); 19 }; 20 "bums".reverse(); //smub 21 </script>

5.2.1 关于内建对象的讨论

 如果想通过原型为某个对象添加一个新属性,务必检查一下该属性是否已经存在。

5.2.2 原型陷阱

 注意: 1> 当对原型对象执行完全替换时,可能会触发原型链中某种异常

            2> prototype.constructor 属性不可靠

 1 <script type="text/javascript">
 2         function Dog(){
 3             this.tail=true;
 4         };
 5         var f1=new Dog();
 6         var f2=new Dog();
 7         // 仍可以为Dog()的原型添加属性,添加之前已经存在的对象也可访问新属性
 8         Dog.prototype.say=function(){
 9             return 'worf';
10         };
11         // f1、f2可以访问新方法
12         f1.say();  //"worf"
13         f2.say(); //"worf"
14         // 检查对象的构造器
15         f1.constructor === Dog; // true  正常
16         f2.constructor === Dog;// true  正常
17         Dog.prototype.constructor === Dog; // true
18 
19         // 用自定义新对象完全覆盖掉原有的原型对象
20         Dog.prototype={
21             paws:4,
22             hair:true
23         };
24         // 这样原有对象不能访问新属性,但通过__proto__与原有的原型保持联系
25         f1.paws; //undefined
26         f1.say();  //"worf"
27         typeof f1.__proto__.say; // "function"
28        // 之后创建的对象室友被更新后的prototype对象
29        var f3=new Dog();
30        f3.say(); // f3.say is not a function
31        f3.tail; // true
32        f3.paws; // 4
33        // __proto__指向新的原型对象
34        f3.__proto__.hair; //true
35 
36        // 新对象的constructor属性不在保持正确
37        f3.constructor;// function Object() { [native code] }
38                       // 本应该指向Dog(),现在指向Object
39        f1.constructor; //function Dog(){this.tail=true;}  仍为Dog() 不变
40        Dog.prototype.constructor; // function Object() { [native code] }
41        //重新设置constructor属性 解决
42        Dog.prototype.constructor=Dog;
43        new Dog().constructor === Dog; // true
44     </script>

 

 

 

posted @ 2017-07-29 09:45  锋aa  阅读(191)  评论(0编辑  收藏  举报