zoukankan      html  css  js  c++  java
  • Javascript 对象创建多种方式 原型链

    一、对象创建

    1、new Object 方式

      直接赋上属性和方法

    var obj = new Object(); 
    obj.name = '娃娃';
    obj.showName = function(){ 
      alert(obj.name);
    }
    //调用 obj.showName();

      缺点:每次使用都要写同样的代码,不能重用

    2、工厂方法方式

      把同样的代码封装在一个函数方法里,是对1、改进,减少重复代码。 

    function CreatePerson(name){ 
       var obj = new Object();   //原料
       obj.name = name;         //加工
       obj.showName = function(){
         alert(this.name);
     } 
       return obj;//出厂
    }
    var p1 = CreatePerson('哇哇');
    p1.showName();
    var p2 = CreatePerson('哈哈');
    p2.showName();
    //其实就是简单的封装函数,整个过程像工厂的流水线,所以叫工厂方式

      缺点:无法识别创建的对象的类型。因为全部都是Object,没有区分度,不像Date、Array等,因此出现了构造函数模式。

    3、构造函数方式

      函数名首字母大写,这是为了和普通函数区分,而且有this指针。

    function CreatePerson(name){ 
       this.name = name; 
       this.showName = function(){ 
         alert(this.name);
       } 
    } 
    var p1 = new CreatePerson('娃娃'); 
    p1.showName();
    var p2 = new CreatePerson('哈哈'); 
    p2.showName();

      构造函数本身也是普通函数,取决于使用的方式,可以new(当作构造函数),也可以直接调用(当作普通函数),两者区别是this指针指向不一样。

    new CreatePerson('haha'); //CreatePerson
    CreatePerson('haha');  //window

      new 内部操作

    function CreatePerson(name){ 
       var obj = {}; //声明一个空对象obj 
       obj._proto_= CreatePerson.prototype;
       //把这个对象的_proto_属性指向构造函数的原型对象,这样obj就可以调用CreatePerson原型对象下的所有方法 。
        CreatePerson.apply(obj);   //用apply方法让this指向obj对象
        this.name = name;   //obj对象添加属性,方法
        this.showName = function(){ 
           alert(this.name);
          }; 
        return obj;//返回这个对象
    }

      缺点:可见这两个对象并不是共用一个方法,每new一次,系统都会新创建一个内存,这两个对象各自有各自的地盘,但他们具有相同的功能,还不共用。

    alert(p1.showName==p2.showName);//false

    4、原型+构造函数方式 最优方式

      原型:

        每个函数都有一个prototype属性,它是一个对象,也称作原型对象,我们可以把方法和属性写在它上面(不过原型对象不仅仅有我们写的属性和方法,还有别的),设计时概念。

        而通过这个函数创建出来的实例对象,都能共享这个原型对象下的方法和属性。

      编写方法:

      把共享的属性和方法定义在函数的prototype下,不共享的内容通过构造函数来创建。

    function CreatePerson(name){ 
      //定义不共享内容
      this.name = name;
    }
    //定义共享内容
    CreatePerson.prototype.showName = function(){ 
       alert(this.name);
    }
    var p1 =new CreatePerson('娃娃');
    p1.showName();
    var p2 = new CreatePerson('哈哈');
    p2.showName();
    alert(p1.showName==p2.showName);//true

      由此也可以看出,showName()方法是共享的,也就是说他们共用一个内存,更进一步的说它们存在引用关系,也就是说你更改了p1的showName也会影响p2的showName。

      _proto_属性:

      运行时属性,每个实例化对象都有_proto_属性,它是一个指针,指向函数的prototype(设计时属性),保存了函数的prototype的地址,通过该_proto_属性可以让同一构造函数的多个实例对象能共享这个构造函数的prototype(设计时定义)下的方法和属性。

      js中任何对象的值都是保存在堆内存中,我们声明的变量只是一个指针,保存了这个对象的实际地址,所以有了地址就能找到对象。

      所以,_proto_属性实际就是实例化对象和原型对象之间的连接。

    二、原型链

      每个函数都可以成为构造函数,每个函数都有原型对象,每个原型对象也可以是一个实例化对象。

      创建了构造函数Function的实例化对象fun,而Function的原型对象(Function.prototype),又是Object的实例对象,根据前边介绍,fun有个_proto_属性,指向了Function.prototype,而Function.prototype(是Object的实例对象)又指向了Object.prototype。

      所以,通过_proto_属性,就形成了一条原型链。每个实例化对象都可以访问到链子上方的方法和属性,所以fun是可以访问Object原型对象下的方法和属性的。实际上所有对象都可以访问到Object的原型对象。

       访问规则先在自身的下面寻找,再去一级一级的往原型链上找
      
    function Aaa(){}
    Aaa.prototype.num = 3;
    var a1 = new Aaa();
    a1.num =10;
    alert(a1.num); //10

  • 相关阅读:
    How to install VXDIAG Honda, Toyota and JLR SDD software
    16% off MPPS V16 ECU tuning tool for EDC15 EDC16 EDC17
    Cummins INSITE locked and ask for verification code
    How to use BMW Multi Tool 7.3 to replace lost key for BMW X1
    Bleed Brake Master Cylinder with Intelligent Tester IT2
    Porsche Piwis Tester II “No VCI has been detected”,how to do?
    Creader VIII VS. Creader VII+
    How to solve GM MDI cannot complete the installation
    汽车OBD2诊断程序开发 (原文转载,思路很清晰!)
    汽车节温器单片机开发思路
  • 原文地址:https://www.cnblogs.com/shawnhu/p/8470560.html
Copyright © 2011-2022 走看看