JavaScript面向對象編程——原型

原型的概念

原型是什麼

在JavaScript中,函數時一個包括屬性和方法的Function類型的對象。而原型(Prototype)就是Function類型對象的一個屬性。
在函數定義時就包含了protoype屬性,它的初始值是一個空對象。在JavaScript中並無定義函數的原始類型,因此原型能夠是任何類型。
原型是用於保存對象的共享屬性和方法的,原型的屬性和方法並不會影響函數自己的屬性和方法。數組

Function類型的屬性 -> 全部函數都具備的屬性
console.log(Function.prototype);
// 定義函數
function fn(){
    console.log('this is function');
}
// 原型的默認值是空對象
console.log(fn.prototype);
// 函數包含構造函數 -> 全部引用類型其實都是構造函數
console.log(Number.prototype);

console.log(Object.prototype);

var result = Object.getOwnPropertyDescriptor(Object.prototype, 'constructor');
console.log(result);

獲取原型

經過下面代碼方式獲取對象的原型,從而設置共享的屬性和方法。函數

function fn(){
    console.log('this is function');
}
// 使用訪問對象的屬性語法結構
console.log(fn.prototype);
console.log(fn['prototype']);
// Object類型提供getPrototypeOf()方法
console.log(Object.getPrototypeOf(fn));

原型的屬性和方法

function fn(){
    console.log('this is function');
}
// 變量proto也是一個空對象
// var proto = fn.prototype;

// 新增屬性或方法
// proto.name = '張無忌';
fn.prototype.name = '張無忌';
console.log(fn.prototype);
// defineProperty()
Object.defineProperty(fn.prototype, 'age', {
    value : 18,
    enumerable : true
});
console.log(fn.prototype);

原型屬性

自主屬性與原型屬性

1.自有屬性:經過對象的引用添加的屬性。其餘對象可能無此屬性;即便有,也是彼此獨立的屬性。
2.原有屬性:從原型對象中繼承來的屬性,一旦原型對象中屬性值改變,全部繼承自該原型的對象屬性均改變。this

// 定義構造函數
function Hero(){
    this.name = '張無忌';
    this.sayMe = function(){
        console.log('this is function');
    }
}
// 操做構造函數Hero的原型
Hero.prototype.age = 18;
// 利用構造函數來建立對象
var hero = new Hero();
console.log(hero);
// 爲構造函數的原型新增的屬性 -> 構造函數建立的對象中依舊能夠訪問
console.log(hero.age);// 18
// 對象hero中不存在age屬性
var result = Object.getOwnPropertyDescriptor(hero, 'age');
console.log(result);

檢測自有或原型屬性

function Hero(){
    // this.name = '張無忌';// 自有屬性
}
// Hero.prototype.name = '周芷若';

var hero = new Hero();
/*
    Object.hasOwnProperty(prop)方法
    * 做用 - 判斷當前指定屬性是否爲自有屬性
    * 參數
      * prop - 表示指定屬性名稱
    * 返回值 - 布爾值
      * true - 表示存在指定的自有屬性
      * false - 表示不存在指定的自有屬性
 */
// console.log(hero.hasOwnProperty('name'));// true
/*
    使用in關鍵字檢測對象的屬性
    * 做用 - 判斷對象中是否存在指定屬性(自有屬性或原型屬性)
    * 返回值 - 布爾值
      * true - 表示存在指定的屬性
      * false - 表示不存在指定的屬性
 */
console.log('name' in hero);

擴展屬性或方法

經過原型能夠爲指定構造函數或對象擴展其屬性或方法。prototype

function fn(){
    console.log('this is function');
}
// 變量proto也是一個空對象
// var proto = fn.prototype;

// 新增屬性或方法
// proto.name = '張無忌';
fn.prototype.name = '張無忌';
console.log(fn.prototype);
// defineProperty()
Object.defineProperty(fn.prototype, 'age', {
    value : 18,
    enumerable : true
});
console.log(fn.prototype);

重寫原型屬性

經過構造函數或對象的自有屬性能夠重寫原型的屬性調試

// 定義構造函數
function Hero(){
    this.name = '張無忌';
}
// 構造函數的原型
Hero.prototype.name = '周芷若';
// 構造函數建立對象
var hero = new Hero();
// 自有屬性與原型屬性同名時,默認訪問的是自有屬性 -> 自有屬性的優先級別高於原型屬性
console.log(hero.name);// 張無忌

// 刪除對象的屬性
delete hero.name;
// 從新訪問對象的屬性
console.log(hero.name);// 周芷若

刪除屬性

經過delete關鍵字能夠刪除對象的屬性,若是該對象即具備原型屬性又具備自有屬性,首先就要刪除自有屬性,再刪除原型屬性。code

function Hero(){}
Hero.prototype = {
        name:'Mary',salary:3800
};
var hero = new Hero();
hero.name = "Tom";

delete hero.name;//刪除Tom
console.log(hero.name);//Mary

delete hero.name;//刪除Mary
console.log(hero.name);//undefined

isPrototypeOf()方法

每一個對象中都會基友一個isPrototypeOf()方法,該方法用來判斷一個對象是不是另外一個對象的原型。對象

// 經過初始化器方式定義對象
var obj = {
    name : '張無忌'
}
// 定義構造函數
function Hero(){}
// 將對象obj賦值給構造函數Hero的原型
Hero.prototype = obj;
// 經過構造函數建立對象
var hero = new Hero();
// 判斷指定對象是不是另外一個對象的原型
var result = obj.isPrototypeOf(hero);

console.log(result);

——proto——屬性繼承

// 經過初始化器方式定義對象
var obj = {
    name : '張無忌'
}
// 定義構造函數
function Hero(){}
// 將對象obj賦值給構造函數Hero的原型
Hero.prototype = obj;
// 經過構造函數建立對象
var hero = new Hero();
// 判斷指定對象是不是另外一個對象的原型
var result = obj.isPrototypeOf(hero);

console.log(result);

上述代碼中說明hero對象存在一個指向構造函數Hero的原型,這個連接被叫作——proto——屬性。
須要注意的是——proto——屬性與prototype屬性並不等價。——proto——屬性只能調試時使用。
——proto——屬性是指定對象的屬性。
prototype屬性是指定構造函數的屬性。ip

擴建內建對象

JavaScript中的內置對象有些也具備prototype屬性,利用內置對象的prototype屬性能夠爲內置對象擴展屬性或方法。
經過原型擴展內置對象的屬性和方法很是靈活,根據個性化要求制定JavaScript語言的具體內容。通常建議謹慎使用這種方法,若是JavaScript的版本更新是可能會提供個性化的屬性或方法,致使衝突。get

Object.prototype.sayMe = function(){
    console.log('this is sayMe function');
}
// 經過Object構造函數建立對象
var obj = new Object();

obj.sayMe();


Array.prototype.inArray = function(color){
    // this - 表示當前的數組
    for(var i = 0, len = this.length; i < len; i++){
        if(this[i] === color){
            return true;
        }
    }
    return false;
}
var arr = ["red", "green", "blue"];

console.log(arr.inArray("red")); //true
console.log(arr.inArray("yellow")); //false
相關文章
相關標籤/搜索