面向?qū)ο?2-原型對象與實(shí)例

原型對象

01 原型對象概念

  • 在構(gòu)造函數(shù)創(chuàng)建出來的時(shí)候,系統(tǒng)會(huì)默認(rèn)幫構(gòu)造函數(shù)創(chuàng)建一個(gè)關(guān)聯(lián)的新對象,就是原型對象,其默認(rèn)為一個(gè)空對象
  • 構(gòu)造函數(shù)找到原型對象:prototype
  • 原型對象找到構(gòu)造函數(shù):constructor

注意:原型對象本身也是一個(gè)對象,這個(gè)對象是Object類型,有一個(gè)屬性constructor

02 原型對象的作用

  • 構(gòu)造函數(shù)的原型對象的屬性與方法可以被構(gòu)造函數(shù)創(chuàng)建的對象共享

03 如何訪問原型對象

  • 構(gòu)造函數(shù).prototype
  • 對象.__ proto__(注意:正常開發(fā)中不要使用這個(gè)屬性,因?yàn)镋CMA標(biāo)準(zhǔn)中并沒有這個(gè)屬性,是瀏覽器開發(fā)商提供的方便調(diào)試,直到E6納入了標(biāo)準(zhǔn)中)
  • Object.getPrototypeOf(對象)

04 如何使用原型對象

  • 利用對象的動(dòng)態(tài)特性

    實(shí)例成員:實(shí)例對象的屬性與方法
    
    原型成員:原型對象上的屬性與方法
    

代碼示例

    function Person(name,age) {
        this.name = name;
        this.age = age;
    }

    Person.prototype.showName = function () {
        console.log(this.name);
    }
    Person.prototype.showAge = function () {
        console.log(this.age);
    };
    Person.prototype.des = "描述信息";

    var p1 = new Person("張三",20);
    console.log(p1);
    console.log(Person.prototype);

    //刪除原型對象上面的屬性
    //delete Person.prototype.des;   //刪除成功
    console.log(p1.des);

    //刪除對象中不存在的屬性,返回true
    console.log(delete p1.des);   //不能使用這種方式直接刪除原型對象上面的屬性
    console.log(p1.des);
  • 字面量的方式直接替換

代碼示例1

   function Person(name,age) {
        this.name = name;
        this.age = age;
    }

    Person.prototype = {
        showName:function () {
            console.log(this.name);
        },
        showAge:function () {
            console.log(this.age);
        },
        des:"描述信息",
        friends:["烏拉烏拉","嘩啦嘩啦","滴答滴答"]
    }

    var p1 = new Person("張三",20);
    var p2 = new Person("張四",20);
    p1.showName();
    p2.showName();

    //原型成員會(huì)被所有的對象(構(gòu)造函數(shù))共享
    p1.des = "測試";        //該行代碼添加屬性在p1上面,并不會(huì)改變原型屬性
    console.log(p2.des);         //描述信息
    console.log(p1);
    console.log(p2);

    p1.friends.push("巴拉巴拉");
    console.log(p1);
    console.log(p2);  //會(huì)受到影響

    //使用對象.這種方式來設(shè)置屬性的時(shí)候,
    // 如果這個(gè)屬性是值類型那么表示添加一個(gè)實(shí)例屬性des,不會(huì)修改原型屬性
    // 如果這個(gè)屬性是引用類型,那么可以修改到原型屬性

    Person.prototype.des = "0000";
    console.log(p1.des);  //測試
    console.log(p2.des);  //0000

注意:使用字面量方式替換原來的原型對象,需要手動(dòng)添加構(gòu)造器屬性,因?yàn)樽置媪縿?chuàng)建的對象本身沒有構(gòu)造器屬性,那么會(huì)去他的原型對象上找,而通過字面量創(chuàng)建的對象是由Object創(chuàng)建的,其原型對象的構(gòu)造器屬性為object,所以在沒有添加構(gòu)造器屬性之前,Person.prototype.constructor = Object

代碼示例2

    function Person(name,age) {
        this.name = name;
        this.age = age;
    }

//    var o = {};
//    var o = new Object();

    //字面量創(chuàng)建的對象是Object創(chuàng)建的
    //該對象的構(gòu)造函數(shù)是 Object
    //該對象的構(gòu)造函數(shù)也有自己的原型對象 Object.prototype
    //該對象的構(gòu)造函數(shù)也有自己的原型對象,內(nèi)部有構(gòu)造器屬性 Object.prototype.constructor =》Object,所以需要手動(dòng)添加一個(gè)構(gòu)造器屬性
    //對象本身并沒有構(gòu)造器屬性,在訪問該屬性的時(shí)候訪問的是其原型對象上面的屬性
    Person.prototype = {
        constructor:Person,
        showName:function () {
            console.log(this.name);
        },
        showAge:function () {
            console.log(this.age);
        }
    };
    var p1 = new Person("張三",20);

    console.log(Person.prototype.constructor == Person); //Person
    console.log(p1);

代碼示例

    function Dog() {
    }
    //構(gòu)造函數(shù) Dog
    //構(gòu)造函數(shù)的原型對象  Dog.prototype
    //原型對象找到構(gòu)造函數(shù) Dog.prototype.constructor ==>Dog

    Dog.prototype.name = "默認(rèn)的名稱";
//    Dog.prototype = {
//        name:"默認(rèn)的名稱"
//    };
    console.log(Dog.prototype);

    var dog1 = new Dog();
    var dog2 = new Dog();
    console.log(dog1.name);
    console.log(dog2.name);
    console.log(dog1.\_\_ proto\_\_== Dog.prototype);  //true
    console.log(Object.getPrototypeOf(dog2) == Dog.prototype);  //true

05 構(gòu)造函數(shù),原型對象與對象的關(guān)系


06 原型對象解決函數(shù)共享問題

建議:屬性寫在構(gòu)造函數(shù)上,方法寫在原型對象上

注意:對象訪問屬性與方法時(shí),會(huì)先在自己身上查找,沒有再去原型對象上查找。

代碼示例

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

    //設(shè)置構(gòu)造函數(shù)的原型對象
    Person.prototype.showName = function () {
        console.log(this.name);
    }

    var p1 = new Person("張三");
    var p2 = new Person("張三豐");
    p1.showName(); //張三
    p2.showName(); //張三豐
    console.log(p1.showName == p2.showName); //true

    //注意:下面的代碼在p1上面添加了一個(gè)showName方法并沒有修改原型對象。
    p1.showName = function () {
        console.log("測試");
    };
    p1.showName(); //測試
    p2.showName(); //張三豐

07 原型對象位置設(shè)置問題

注意:在設(shè)置(替換)原型對象前后創(chuàng)建的對象指向的原型對象不是同一個(gè)

代碼示例

    //01 提供構(gòu)造函數(shù)
    function Person(name,age) {
        this.name = name;
        this.age = age;
    }

    //03 創(chuàng)建實(shí)例對象
    var p1 = new Person("張三",20);

    //02 設(shè)置原型對象
    Person.prototype = {
        constructor:Person,
        showName:function () {
            console.log(this.name);
        }
    }


    var p2 = new Person("李四",20);
    p2.showName();  //李四
    p1.showName();  //報(bào)錯(cuò),因?yàn)閜1是在替換原型對象之前創(chuàng)建的,其原型對象只有一個(gè)constructor屬性,沒有showName方法,所以報(bào)錯(cuò)。

08 hasOwnProperty方法

hasOwnProperty:判斷某個(gè)對象是否擁有指定的實(shí)例屬性(不包括原型成員)

in關(guān)鍵字 :檢查對象是否擁有指定的成員(實(shí)例成員與原型成員)

代碼示例

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

    Person.prototype.hi = "hi";
    Person.prototype.show = function () {

    };
    var p1 = new Person();

    //語法 對象.hasOwnProperty("屬性")
    console.log(p1.hasOwnProperty("name")); //true
    console.log(p1.hasOwnProperty("age"));  //false
    console.log(p1.hasOwnProperty("hi"));   //false

    //語法 “屬性” in 對象
    console.log("name" in p1);           //true
    console.log("age" in p1);            //false
    console.log("hi" in p1);              //true
    console.log("show" in p1);           //true

09 isPrototypeOf方法

isPrototypeOf:判斷某個(gè)對象是否是另一個(gè)對象的原型對象

代碼示例

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

    var obj = {};
    var o = {
        hi:"hi"
    }
    Person.prototype = o;

    var p1 = new Person("李四");
    
    //Object.prototype Object構(gòu)造函數(shù)的原型對象
    console.log(o.isPrototypeOf(p1));  //true 判斷o是否是p1的原型對象
    console.log(Object.prototype.isPrototypeOf(p1));  //true

實(shí)例化與實(shí)例

實(shí)例化:構(gòu)造函數(shù)創(chuàng)建對象的過程

實(shí)例(對象):構(gòu)造函數(shù)創(chuàng)建出來的對象是該構(gòu)造函數(shù)的一個(gè)實(shí)例對象;在說實(shí)例的時(shí)候需要指明構(gòu)造函數(shù)。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容