zoukankan      html  css  js  c++  java
  • JavaScript中的 原型 property 构造函数 和实例对象之间的关系

     1 为什么要使用原型?

     1 /*
     2  *    javascript当中 原型 prototype 对象
     3  * 
     4  * */
     5 //首先引入 prototype的意义,为什么要使用这个对象
     6 
     7 //先来写一个构造函数的面向对象实例
     8 function Person(name ){
     9     this.name = name;
    10     this.show = function(){
    11         return this.name;
    12     };
    13 }
    14 //实例化两个对象
    15 p1 = new Person("a");
    16 p2 = new Person("b");
    17 //alert(p1 == p2); // false    很显然两个实例对象不是一个对象
    18 //alert(p1.show == p2.show);    // false    实际上每一个对象实例化的时候都各自拥有自己的这个方法
    19 
    20 
    21 /*
    22  *   实际上,上面的例子,对于show函数来说,其实每一个Person的对象,都拥有这个方法,并且功能是一样的,这其实是占用内存的,重复累赘的
    23  *         如果可以更好的 话,一个面向对象过程,相同的属性和方法,最好还是能所有对象拥有同一份公共相同方法和属性,
    24  * 
    25  * 
    26  *     在js当中这就需要引入原型的概念:
    27  *         在js中,每一个函数都有一个属性prototype 是一个指向自己的原型对象的引用。
    28  *         原型对象是一个对象, 如果我们把希望共有的方法和属性写入原型对象当中,就能实现,在每一个实例化对象不新建一个方法和属性,
    29  *             而是使用原型对象的提供的方法和属性 
    30  * 
    31  * */
    32 
    33 //这是一个类
    34 function Person(){
    35     
    36 }
    37 //下面我们向这个Person类的原型对象里面添加属性和方法
    38 Person.prototype.name = "张三";
    39 Person.prototype.show = function(){
    40     return this.name;
    41 };
    42 
    43 //实例化两个Person的对象
    44 var p1 = new Person();
    45 var p2 = new Person();
    46 //alert(p1.name);    //张三
    47 //alert(p1.name == p2.name);    //true 加入原型对象的属性就变成了公共属性,所有对象拥有相同一份
    48 //这个时候我们给p1 增加自己的变量 覆盖name
    49 p1.name = "李四";
    50 //alert(p1.show());    //李四    这个name变量实际上没有覆盖原型类当中,而是p1对象自己的成员变量
    51 //这个时候把p1的name删除,再取p1的name,就又会取到原型对象的name
    52 delete p1.name;
    53 //alert(p1.show());    //张三   这个时候,自己没有成员变量name , 就会使用原型对象中共有的name
    54 
    55 //alert(p1.show == p2.show);    // true   这两个实例对象都没有实现show  这个show是原型类提供的
    56 
    57 
    58 /*
    59  * 经过上面的分析 再来整理一下 原型对象:
    60  * 
    61  *     1 任何一个函数 他的prototype属性都是一个指向自己原型对象的引用
    62  *     2 某个函数实例在调用方法或者取属性的时候,先找自己的成员变量,如果没有再找自己的原型对象中的共有变量
    63  *  3 相同构造函数出来的所有实例对象的protorype 指向的原型 都和构造函数的原型是同一个原型对象
    64  *  4 写入原型中的方法和属性是共有的,如果实例对象重写,会添加私有变量 不会覆盖原型中的内容
    65  *  5 原型对象的构造器指向的就是拥有这个原型的初始的构造函数。
    66  * 
    67  * */

     

     

    2 构造函数 实例对象 和原型对象的关系

     1 /*
     2     JavaScript中 构造函数、实例对象、原型之间的关系:
     3     构造函数内的变量和方法,每一个实例对象初始化的时候都会为自己实例化这些属性方法
     4     构造函数的prototype属性,是一个引用,指向他的原型对象
     5     构造函数实例化出来的所有对象和构造函数共有一个原型对象,他们的prototype都指向同一个原型
     6     原型对象中的属性方法是构造函数和实例对象共有的,实例对象初始化不会为自己创建这些属性和方法。
     7     当调用实例对象的属性的时候,会有限找自己的私有变量,没有的话就去找原型对象的变量,再没有就返回undefined
     8     
     9 */
    10 //一个构造函数
    11 function Person(){
    12     
    13 }
    14 //Person的原型对象 设置公共属性和方法
    15 Person.prototype.name="haha";
    16 Person.prototype.age=18;
    17 Person.prototype.sayName = function(){
    18     alert(this.name);
    19 };
    20 
    21 // 实例化对象
    22 var p1 = new Person();
    23 alert(p1.name);    //haha    这里会找到原型对象中的公共属性
    24 
    25 //利用Object.getPrototypeOf(obj) 能够取得obj的原型对象
    26 alert(Person.prototype == Object.getPrototypeOf(p1));    //true 构造函数实例化的对象他们之间共有一个原型对象
    27 
    28 
    29 
    30 /*
    31     当调用对象属性的时候
    32     先搜索自己的私有属性 
    33     如果没有 再搜索原型对象的属性
    34     如果没有 返回undefined
    35     
    36     对象设置私有属性不会修改原型内容,只会自己添加属性
    37 */
    38 //实例化另一个对象 
    39 var p2 = new Person();
    40 //给p2添加私有属性 
    41 p2.name = "xixi";
    42 alert(p2.name);    //xixi
    43 delete p2.name;
    44 alert(p2.name);    //haha
    45 
    46 
    47 // 检查一个对象的属性是不是自己的 hasOwnProperty()
    48 p2.name = "xixi";
    49 alert(p2.name);    //xixi
    50 alert(p2.hasOwnProperty("name"));    //true
    51 delete p2.name;
    52 alert(p2.name);    //haha
    53 alert(p2.hasOwnProperty("name"));    //false
    54 
    55 // in 操作符 返回 属性是否在对象中或者在原型中
    56 alert( "name" in p2 );    //true
    57 
    58 // 结合in和hasOwnProperty  判断 属性是不是原型的属性
    59 function isPrototypeProperty( obj , property ){
    60     // 不是自己的私有属性并且是自己的属性
    61     return !obj.hasOwnProperty(property) && property in obj;
    62 }
    63 
    64 
    65 //Object.keys(obj) 返回obj对象中能够被枚举的私有属性的数组  constructor 是不能被枚举的
    66 p2.name = "xixi";
    67 p2.age=10;
    68 alert(Object.keys(p2));    // name,age
    69 alert(Object.keys(Person.prototype));    //name,age,sayName
    70 
    71 // Object.getOwnPropertyNames(obj) 返回obj所有属性的数组
    72 alert(Object.getOwnPropertyNames(Person.prototype));    // name,age,sayName,constructor
  • 相关阅读:
    第二次Soring冲刺计划第四天(团队)
    第二次Soring冲刺计划第四天(个人)
    第二次Soring冲刺计划第三天(团队)
    第二次Soring冲刺计划第三天(个人)
    第二次Soring冲刺计划第二天(团队)
    第二次Soring冲刺计划第二天(个人)
    第二次Soring冲刺计划第一天(个人)
    2018.12.6
    2108.12.5
    2018.12.4
  • 原文地址:https://www.cnblogs.com/Lin-Yi/p/7437510.html
Copyright © 2011-2022 走看看