[js高手之路]原型對象(prototype)與原型鏈相關屬性與方法詳解

一,instanceof:

instanceof檢測左側的__proto__原型鏈上,是否存在右側的prototype原型. 我在之前的兩篇文章

[js高手之路]構造函數的基本特性與優缺點

[js高手之路]一步步圖解javascript的原型(prototype)對象,原型鏈

已經分享過了.

function CreateObj(uName) {
            this.userName = uName;
            this.showUserName = function () {
                return '100';
            }
        }
        CreateObj.prototype.showUserName = function () {
            return this.userName;
        }
        var obj1 = new CreateObj('ghostwu');
        var obj2 = new CreateObj('衛莊');
        console.log( obj1 instanceof CreateObj ); //true
        console.log( obj2 instanceof CreateObj ); //true
        console.log( obj1 instanceof Object ); //true
        console.log( obj2 instanceof Object ); //true

二、isPrototypeOf:

如果隱式原型__proto__指向調用isPrototypeOf()方法的對象原型( CreateObj ), 那麼這個方法就返回true,如:

1         var obj1 = new CreateObj('ghostwu');
2         var obj2 = new CreateObj('衛莊');
3         console.log( CreateObj.prototype.isPrototypeOf( obj1 ) ); //true
4         console.log( CreateObj.prototype.isPrototypeOf( obj2 ) ); //true

因爲obj1,obj2的隱式原型__proto__指向的都是CreateObj.prototype, 有朋友可能會問CreateObj.prototype上面根本就沒有isPrototypeOf這個方法,怎麼可以

調用呢?

是的,沒錯,但是CreateObj.prototype的隱式原型__proto__指向了Object.prototype, 而isPrototypeOf存在Object.prototype上,所以就能夠調用

三、Object.getPrototypeOf

獲取實例的隱式原型(__proto__)的指向,因爲obj1,obj2的__proto__都指向CreateObj.prototype

var obj1 = new CreateObj('ghostwu');
        var obj2 = new CreateObj('衛莊');
        console.log( Object.getPrototypeOf( obj1 ) === CreateObj.prototype ); //true
        console.log( Object.getPrototypeOf( obj2 ) === CreateObj.prototype ); //true


四,實例訪問屬性和方法時,遵循就近查找原則

實例先在自己身上查找,有,就停止查找,如果沒有,就沿着實例的__proto__繼續往上查找,有,就停止查找,如果沒有就繼續沿着原型鏈一直往上查找,如果

所有的原型對象上都沒有,那就是undefined.

function CreateObj(uName) {
            this.userName = uName;
        }
        CreateObj.prototype.showUserName = function () {
            return this.userName;
        }
        CreateObj.prototype.age = 22;
        var obj1 = new CreateObj('ghostwu');
        obj1.age = 20;
        var obj2 = new CreateObj('衛莊');
        console.log( obj1.age ); //20--->來自實例
        console.log( obj2.age ); //22--->來自原型對象
        delete obj1.age;
        console.log( obj1.age ); //22--->來自原型


五,hasOwnProperty

判斷屬性是實例上的還是原型對象上的,如果是實例上的,返回true, 原型上的返回false

function CreateObj(uName) {
            this.userName = uName;
        }
        CreateObj.prototype.showUserName = function () {
            return this.userName;
        }
        CreateObj.prototype.age = 22;
        var obj1 = new CreateObj('ghostwu');
        obj1.age = 20;
        var obj2 = new CreateObj('衛莊');
        console.log( obj1.age ); //20--->來自實例
        console.log( obj1.hasOwnProperty( 'age' ) ); //true
        console.log( obj2.age ); //22--->來自原型對象
        console.log( obj2.hasOwnProperty( 'age' ) ); //false
        delete obj1.age;
        console.log( obj1.age ); //22--->來自原型
        console.log( obj1.hasOwnProperty( 'age' ) ); //false

六、in操作符

判斷屬性是否在實例或者原型對象上,只要一個滿足條件,返回值都是true

function CreateObj(uName) {
            this.userName = uName;
        }
        CreateObj.prototype.showUserName = function () {
            return this.userName;
        }
        CreateObj.prototype.age = 22;
        var obj1 = new CreateObj('ghostwu');
        obj1.age = 20;
        console.log( 'age' in obj1 ); //true
        var obj2 = new CreateObj('衛莊');
        console.log( 'age' in obj2 ); //true
        delete obj1.age;
        console.log( 'age' in obj1 ); //true
        console.log( 'user' in obj1 ); //false
        console.log( 'user' in obj2 ); //false


七,結合in和hasOwnProperty的用法,可以封裝一個函數判斷這個屬性是否在原型對象上, 返回值爲true:在原型對象上, false:不在原型對象上

function CreateObj(uName) {
            this.userName = uName;
        }
        CreateObj.prototype.showUserName = function () {
            return this.userName;
        }
        CreateObj.prototype.age = 20;
        function hasPrototypeProperty( obj, name ){
            return !obj.hasOwnProperty( name ) && ( name in obj );
        }
        var obj1 = new CreateObj('ghostwu');
        var obj2 = new CreateObj('衛莊');
        obj1.age = 10;
        console.log( hasPrototypeProperty( obj1, 'age' ) ); //false
        console.log( hasPrototypeProperty( obj2, 'age' ) ); //true

八、for...in 可以枚舉實例和原型對象上的屬性和方法,前提是:該屬性和方法是可以枚舉

function CreateObj(uName) {
            this.userName = uName;
        }
        CreateObj.prototype.showUserName = function () {
            return this.userName;
        }
        CreateObj.prototype.age = 20;
        var obj = new CreateObj( 'ghostwu' );
        for( var key in obj ){
            console.log( key ); //userName,age,showUserName
        }
        console.log( Object.prototype );
        for( var key in Object.prototype ){
            console.log( key );//枚舉不了, Object.prototype上的屬性和方法默認不可枚舉,枚舉屬性爲false
        }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章