1. 程式人生 > >js(ES5)面向物件

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 constructorCreatePerson()這個建構函式 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的原型物件。
      原型鏈的訪問規則:先在自身的下面尋找,再去一級一級的往原型鏈上找。*/