js(ES5)面向對象以及原理

                                                             普通對象和函數對象
//    var o1={};
//    var o2=new Object();
//    var o3=new f1();

//    凡是經過 new Function() 建立的對象都是函數對象,其餘的都是普通對象,系統內置的函數對象Function,Object,Array,String,Number
//    function f1() {
//
//    }
//    var f2=function () {
//
//    }
//    var f3=new Function("str","");
//
//    console.log(typeof o1); //object
//    console.log(typeof o2); //object
//    console.log(typeof o3); //object
//
//
//    console.log(typeof f1); //function
//    console.log(typeof f2); //function
//    console.log(typeof f3); //function

    

                                                                                            構造函數:

/*-------------------------構造函數constructor --------------------*/
    function Person(name,age,job) {
        this.name=name;
        this.age=age;
        this.job=job;
        this.sayName=function () {
            alert(this.name)
        }
//        若忽略return則意味着返回this對象
        console.log("++++++this",this)  // Person{}  不寫new ,當成普通函數,指向widow
    }
//     person1 和 person2 都是 構造函數 Person 的實例    實例person1和 person2 的構造函數屬性(constructor)指向構造函數Person 。
//        person1.constructor == Person
    var person1=new  Person("lichuyan",23,"web");
//    .將構造函數中的Person的this指向對象person1。相對於普通函數,構造函數中的this是指向實例的,而普通函數調用中的this是指向windows的。
    var person2=new Person("yuanmingqi",23,"java");

    console.log("person1==person2",person1.sayName==person2.sayName)  // false
//    缺點:可見這兩個對象並非共用一個方法,每new一次,系統都會新建立一個內存,這兩個對象各自有各自的地盤,但他們具備相同的功能。還不共用,確定不是咱們所但願的。因此就有了下一種方法,原型+構造模式

 

                                                                                                   原型對象

一:原型對象用處是繼承

原型對象是一個普通的對象,
    //    定律1:每一個對象都有 __proto(隱私原型)__ 屬性,但只有函數對象纔有原型屬性也叫(prototype)原型對象,在這裏是Person.prototype;
    //    因此咱們只須要把想要共享的東西放在函數的prototype下,不想共享的東西經過構造函數來建立。

// 構造模式
    function Person(name,age,job) {
        this.name=name;
        this.age=age;
        this.job=job;
    }

// 原型模式
    Person.prototype.sayName=function () {
        alert(this.name);
    }
    var person3=new  Person("lichuyan",23,"web");
    person3.sayName();
    var person4=new Person("yuanmingqi",23,"java");
    person4.sayName();
    console.log("person3==person4",person3.sayName==person4.sayName)  // true
//    測試爲true,可見同一個函數造出來的實例對象能共享這個函數的prototype下的方法和屬性即showName()方法是共享的,也就是說他們共用一個內存,更進一步的說它們存在引用關係,也就是說你更改了p3的showName也會影響p4的showName

二:原型對象下可能有三種屬性

 // 構造模式

function CreatePerson(name){
        this.name = name;
    }

  // 原型模式
    CreatePerson.prototype.showName = function(){
        console.log(this.name);
    };
    var p1 =new CreatePerson('haha');

實例化對象怕p1經過_proto_屬性共享了原型對象的屬性和方法
    p1.showName();
    console.log("++++++++++實例p1",p1);
    console.log("++++++++++實例p1的構造屬性",p1.constructor); // 指向構造函數

    console.log("++++++++原型對象下的三個屬性",CreatePerson.prototype);

//1 原型對象所帶方法和屬性 2 constructor即CreatePerson()這個構造函數 3_proto_屬性


    console.log("++++++++原型對象額構造屬性",CreatePerson.prototype.constructor);

    console.log("++++++++是否同樣",p1.constructor===CreatePerson.prototype.constructor);
//    結論: 實例person1的構造函數屬性(constructor)指向構造函數CreatePerson=
//         原型對象的構造函數屬性指向構造函數CreatePerson

 

//    1:在默認狀況下,全部的原型對象都會自動得到一個 constructor(構造函數)屬性,這個屬性(是一個指針)指向函數(Person)既Person.prototype.constructor == Person

//    定律2:原型對象(Person.prototype)也是 構造函數(Person)的一個實例。

 

圖

 

 

                                                                                _proto_屬性:

 /* _proto_屬性:
        同一個函數造出來的實例對象能共享這個函數的prototype下的方法和屬性,可是它是如何作到的呢?這裏要出場的就是_proto_屬性.
        每一個實例化對象都有_proto_屬性,它是一個指針,指向函數的prototype,也就是保存了它的地址。
       (JS中任何對象的值都是保存在堆內存中,咱們聲明的變量只是一個指針,保存了這個對象的實際地址,因此有了地址就能找到對象),
       因此總得來講,每一個實例化對象都有_proto_屬性,保存了構造函數的原型對象的地址,經過這個屬性就能夠擁有原型對象下的全部屬性和方法,_proto_屬性實際就是實例化對象和原型對象之間的鏈接
*/

 

                                                                             原型鏈:

/*   
       每一個函數均可以成爲構造函數,每一個函數都有原型對象,每一個原型對象也能夠是一個實例化對象,好比,你建立了一個函數fun,
       它是構造函數function的實例化對象,而function的原型對象,又是Object的實例對象。因此fun有個_proto_屬性能夠訪問到function的原型對象,function原型對象也是個實例對象,也有個_proto_屬性,能夠訪問到Object的原型對象,因此經過_proto_屬性,就造成了一條原型鏈。每一個實例化對象均可以訪問到鏈子上方的方法和屬性
      ,因此fun是能夠訪問Object原型對象下的方法和屬性的。實際上全部對象均可以訪問到Object的原型對象。
      原型鏈的訪問規則:先在自身的下面尋找,再去一級一級的往原型鏈上找。*/
相關文章
相關標籤/搜索