讀書筆記 | JavaScript創(chuàng)建對象

參考資料

JavaScript高級程序設(shè)計(第3版)

一、理解對象

( 一)對象屬性的分類

JS對象屬性有兩種類型:數(shù)據(jù)屬性和訪問器屬性

1、數(shù)據(jù)屬性

數(shù)據(jù)類型有四個描述其行為的特性:

  • [[Configurable]] : 表示能否通過delete刪除屬性、能否修改屬性的特性(改為訪問器屬性),默認值為true。
  • [[Enumerable]]:是否可(通過for-in)枚舉,默認值為true。
  • [[Writable]]:表示能否修改屬性的值,默認值為true。
  • [[Value]]:包含這個屬性的數(shù)據(jù)值,默認值為undefined。

2、訪問器屬性

訪問器屬性有如下4個特性:

  • [[Configurable]]:同上。
  • [[Enumerable]]:同上。
  • [[Get]:在讀取屬性時調(diào)用的函數(shù),默認值為undefined。
  • [[Set]:在寫入屬性時調(diào)用的函數(shù),默認值為undefined。

(二)定義或修改對象屬性

1、定義或修改數(shù)據(jù)屬性

  • [[Value]]可直接定義,而[[Configurable]] 、 [[Enumerable]]和[[Writable]]只能利用方法Object.definedProperty( )或Object.definedProperties( )修改默認的特性。
  • 一旦調(diào)用方法Object.definedProperty( )或Object.definedProperties( ),若不指定,[[Configurable]] 、 [[Enumerable]]和[[Writable]]的值都改為false。

Object.definedProperty()和Object.definedProperties()是 ES5(ECMAScript5)特有的,部分瀏覽器不兼容。

2、定義或修改訪問器屬性

訪問器屬性不能直接定義,必須使用Object.definedProperty( )來定義。

(三)讀取屬性的特性

利用Object.getOwnPropertyDescriptor(obj,property)讀取指定對象obj的屬性property的值。

二、創(chuàng)建對象

JavaScript中可以使用以下7種模式來創(chuàng)建對象,其中“組合使用構(gòu)造函數(shù)模式和原型模式”使用最廣泛、認同度最高。

(一) 工廠模式

function createStudent(name,country){
    var o=new Object();
    o.name=name;
    o.country=country;
    o.sayName=function(){
        alert(this.name);
    };
    return o;
}
var student1=createStudent("evelyn","China");

缺點:沒有解決對象識別的問題。

(二)構(gòu)造函數(shù)模式

function Student(name,country){
    this.name=name;
    this.country=country;
    this.sayName=sayName;
}
function sayName{
        alert(this.name);
 }
var student1=new Student("evelyn","China");//student1既是Student的實例,也是Object的實例

1、關(guān)于構(gòu)造函數(shù)

構(gòu)造函數(shù)命名必須首字母大寫,而非構(gòu)造函數(shù)應(yīng)該以一個小寫字母開頭。

2、缺點

對象的方法是全局的函數(shù),但卻只被某個對象調(diào)用。另外,如果某個對象有很多方法,就要定義許多全局函數(shù),毫無封裝性可言。

(三) 原型模式

function Student(){
}
Student.prototype={  
    constructor:Student, 
    name:"evelyn",
    country:"China",
    sayName:function(){
         alert(this.name);
    }
};
var student1=new Student();

1、關(guān)于原型

  • hasOwnProperty()用于檢測一個屬性是否存在于實例中,可用于區(qū)分實例屬性和繼承原型的屬性。
  • ES5的Object.getOwnPropertyDescriptor()方法只能用于讀取實例屬性的描述符。
  • "property in obj"通過返回布爾值檢測對象是否有某個屬性(不區(qū)分實例屬性和原型屬性)
  • hasPrototypeProperty()用于檢測一個屬性是否存在于原型中
  • ES5中object.defineProperty()用于定義屬性。
  • 對象字面量形式創(chuàng)建的對象原型相當于重寫原型。

2、關(guān)于枚舉

  • ES5中的constructor和prototype屬性的[[Enumerable]]特性默認為false,因此for in不會枚舉這兩個屬性。
  • for in循環(huán)返回可枚舉的原型對象和實例對象;object.keys()返回可枚舉的實例對象的對應(yīng)數(shù)組;object.getOwnPropertyNames()返回所有的實例屬性(無論是否可枚舉)。

3、缺點

  • 省略傳參環(huán)節(jié),所有實例在默認情況下取得相同屬性值。
  • 單獨使用原型模式的最大缺點在于,原型屬性共享導(dǎo)致實例之間相互影響。

(四)組合使用構(gòu)造函數(shù)模式和原型模式(最常用)

function Student(name,country){
    this.name=name;
    this.country=country;
}
Student.prototype={
    constructor:Person,    //重寫了默認的prototype對象,constructor不再指向Person(而是指向Object),因而重新設(shè)置指向Person
    sayName:function(){
         alert(this.name);
    }
};
var student1=new Student("evelyn","China");

特點:實例共享的屬性和方法在原型中定義,除此之外的實例屬性在構(gòu)造函數(shù)中定義。

(五)動態(tài)原型模式

function Student(name,country){
    this.name=name;
    this.country=country;
    if(typeof this.sayName!="function"){
        Student.prototype.sayName=function(){
             alert(this.name);
        };
    }
};
var student1=new Student("evelyn","China");

(六)寄生構(gòu)造函數(shù)模式

function Student(name,country){
    var o=new Object();
    o.name=name;
    o.country=country;
    o.sayName=function(){
        alert(this.name);
    };
    return o;
}
var student1=new Student("evelyn","China");

(七)穩(wěn)妥構(gòu)造函數(shù)模式

function Student(name,country){
    var o=new Object();
    o.sayName=function(){
        alert(name);
    };  //只能通過sayName方法訪問name的值
    return o;
}
var student1=Student("evelyn","China");
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

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

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