JavaScript中的Object對象學(xué)習(xí)教程
參數(shù):
(1)obj
必需。Object 對象分配到的變量名稱。
(2)值
可選。任一 JavaScript 基元數(shù)據(jù)類型(數(shù)字、布爾值或字符串)。 如果值是一個(gè)對象,則返回的對象是未修改的。 如果值是 null、“未定義”或“未提供”,則創(chuàng)建無內(nèi)容的對象。
Object對象的方法
Object作為構(gòu)造函數(shù)使用時(shí),可以接受一個(gè)參數(shù)。如果該參數(shù)是一個(gè)對象,則直接返回這個(gè)對象;如果是一個(gè)原始類型的值,則返回該值對應(yīng)的包裝對象。利用這一點(diǎn),可以寫一個(gè)判斷變量是否為對象的函數(shù)。
function isObject(value) { return value === Object(value); }
要在Object對象上面部署一個(gè)方法,有兩種做法。
部署在Object對象本身
部署在Object.prototype對象
Object.keys方法和Object.getOwnPropertyNames方法很相似,一般用來遍歷對象的屬性。它們的參數(shù)都是一個(gè)對象,都返回一個(gè)數(shù)組,該數(shù)組的成員都是對象自身的(而不是繼承的)所有屬性名。兩者區(qū)別在于,前者只返回可枚舉的屬性,后者還返回不可枚舉的屬性名。由于數(shù)組存在不可枚舉屬性length,因此一般使用Object.keys遍歷數(shù)組。
JavaScript沒有提供計(jì)算對象屬性個(gè)數(shù)的方法,可通過 Object.keys(o).length 和 Object.getOwnPropertyNames(o).length 獲取。
Object.observe方法用于觀察對象屬性的變化。
原型鏈相關(guān)方法:
Object.create():生成一個(gè)新對象,并該對象的原型。
Object.getPrototypeOf():獲取對象的Prototype對象。
Object實(shí)例對象的方法
Object.prototype.valueOf():valueOf方法的作用是返回一個(gè)對象的值,默認(rèn)情況下返回對象本身。該方法的主要用途是,JavaScript自動類型轉(zhuǎn)換時(shí)會默認(rèn)調(diào)用這個(gè)方法。
Object.prototype.toString():toString方法的作用是返回一個(gè)對象的字符串形式。當(dāng)對象用于字符串加法時(shí),會自動調(diào)用toString方法。
使用call方法,可以在任意值上調(diào)用Object.prototype.toString方法,從而判斷這個(gè)值的類型。不同數(shù)據(jù)類型的toString方法返回值如下:
數(shù)值:返回[object Number]
字符串:返回[object String]
布爾值:返回[object Boolean]
undefined:返回[object Undefined]
null:返回[object Null]
對象:返回”[object “ + 構(gòu)造函數(shù)的名稱 + “]”
Object.prototype.toString.call(2) // "[object Number]" Object.prototype.toString.call('') // "[object String]"
利用這個(gè)特性,可寫出一個(gè)比typeof運(yùn)算符更準(zhǔn)確的類型判斷函數(shù)。
var type = function (o){ var s = Object.prototype.toString.call(o); return s.match(/\[object (.*?)\]/)[1].toLowerCase(); }; type({}); // "object" type([]); // "array" type(5); // "number"
在上面這個(gè)type函數(shù)的基礎(chǔ)上,還可以加上專門判斷某種類型數(shù)據(jù)的方法。
['Null', 'Undefined', 'Object', 'Array', 'String', 'Number', 'Boolean', 'Function', 'RegExp', 'Element', 'NaN', 'Infinite' ].forEach(function (t) { type['is' + t] = function (o) { return type(o) === t.toLowerCase(); }; }); type.isObject({}); // true type.isNumber(NaN); // false type.isElement(document.createElement('div')); // true
對象的屬性模型
在JavaScript內(nèi)部,每個(gè)屬性都有一個(gè)對應(yīng)的attributes對象,保存該屬性的一些元信息。使用Object.getOwnPropertyDescriptor方法,可讀取o對象的p屬性的attributes對象。attributes對象包含如下元信息:
value:表示該屬性的值,默認(rèn)為undefined(只要writable和configurable有一個(gè)為true,就可以改動)。
writable:表示該屬性的值(value)是否可以改變,默認(rèn)為true。
enumerable: 表示該屬性是否可枚舉,默認(rèn)為true,也就是該屬性會出現(xiàn)在for…in和Object.keys()等操作中。一般來說,系統(tǒng)原生的屬性(即非用戶自定義的屬性)都是不可枚舉的。
表示“可配置性”,默認(rèn)為true。如果設(shè)為false,表示無法刪除該屬性,也不得改變attributes對象(value屬性除外,如果writable為true,仍可改變value),也就是configurable屬性控制了attributes對象的可寫性。
表示該屬性的取值函數(shù)(getter),默認(rèn)為undefined。
表示該屬性的存值函數(shù)(setter),默認(rèn)為undefined。
var o = { p: 'a' }; Object.getOwnPropertyDescriptor(o, 'p'); // Object { // value: "a", // writable: true, // enumerable: true, // configurable: true // }
Object.defineProperty方法允許通過定義attributes對象,來定義或修改一個(gè)屬性,然后返回修改后的對象。格式如下:
Object.defineProperty(object, propertyName, attributesObject)
Object.defineProperty方法接受三個(gè)參數(shù),第一個(gè)是屬性所在的對象,第二個(gè)是屬性名(它應(yīng)該是一個(gè)字符串),第三個(gè)是屬性的描述對象。通過此方法定義屬性,屬性對象的writable、configurable、enumerable三個(gè)屬性的默認(rèn)值都為false。
Object.defineProperty(o, "p", { value: "bar" }); Object.getOwnPropertyDescriptor(o, 'p'); // Object { // value: "bar", // writable: false, // enumerable: false, // configurable: false // }
如果一次性定義或修改多個(gè)屬性,可以使用Object.defineProperties方法。需要注意的是,一旦定義了取值函數(shù)get(或存值函數(shù)set),就不能將writable設(shè)為true,或者同時(shí)定義value屬性,否則會報(bào)錯(cuò)。
var o = Object.defineProperties({}, { p1: {value: 123, enumerable: true}, p2: {value: "abc", enumerable: true}, p3: { get: function () { return this.p1 + this.p2 }, enumerable: true, configurable: true } });
enumerable可以用來設(shè)置“秘密”屬性,如果一個(gè)屬性的enumerable為false,則 for..in 循環(huán)、Object.keys 方法和 JSON.stringify 方法都不會取到該屬性,但可以通過 o.xx 直接獲取它的值。
for…in循環(huán)和Object.keys方法的區(qū)別在于,前者包括對象繼承自原型對象的屬性,而后者只包括對象本身的屬性。如果需要獲取對象自身的所有屬性,不管enumerable的值,可以使用Object.getOwnPropertyNames方法。
可配置性決定了一個(gè)變量是否可以被刪除(delete)。當(dāng)使用var命令聲明變量時(shí),變量的configurable為false,而不使用var命令聲明變量時(shí)(或者使用屬性賦值的方式聲明變量),變量的可配置性為true。這說明,delete只能刪除對象的屬性。
var a1 = 1; // configurable: false a2 = 1; // configurable: true(等價(jià)于this.a2 = 1)
除了直接定義以外,屬性還可以用存取函數(shù)(accessor)定義。其中,存值函數(shù)稱為setter,使用set命令;取值函數(shù)稱為getter,使用get命令。利用存取函數(shù),可以實(shí)現(xiàn)數(shù)據(jù)對象與DOM對象的雙向綁定。
Object.defineProperty(user, 'name', { get: function () { return document.getElementById("foo").value }, set: function (newValue) { document.getElementById("foo").value = newValue; }, configurable: true });
控制對象狀態(tài)
JavaScript提供了三種方法,精確控制一個(gè)對象的讀寫狀態(tài),防止對象被改變。最弱一層的保護(hù)是preventExtensions,其次是seal,最強(qiáng)的freeze。
Object.preventExtensions方法可以使得一個(gè)對象無法再添加新的屬性,但可以用delete命令刪除它的現(xiàn)有屬性。Object.isExtensible方法可以用來檢查是否可以為一個(gè)對象添加屬性。
Object.seal方法使得一個(gè)對象既無法添加新屬性,也無法刪除舊屬性。Object.seal還把現(xiàn)有屬性的attributes對象的configurable屬性設(shè)為false,使得attributes對象不再能改變。Object.isSealed方法用于檢查一個(gè)對象是否使用了Object.seal方法。
Object.freeze方法可以使得一個(gè)對象無法添加新屬性、無法刪除舊屬性、也無法改變屬性的值,使得這個(gè)對象實(shí)際上變成了常量。Object.isFrozen方法用于檢查一個(gè)對象是否使用了Object.freeze()方法。
使用上面這些方法鎖定對象的可寫性,但是依然可以通過改變該對象的原型對象,來為它增加屬性。
var o = new Object(); Object.preventExtensions(o); var proto = Object.getPrototypeOf(o); proto.t = "hello"; o.t // hello
一種解決方案是,把原型也凍結(jié)住。
var o = Object.seal( Object.create(Object.freeze({x:1}), {y: {value: 2, writable: true}}) ); Object.getPrototypeOf(o).t = "hello"; o.t // undefined
PS:
Object 對象包含在所有其他 JavaScript 對象中;它的所有方法和屬性均可用于所有其他對象。 方法可在用戶定義的對象中進(jìn)行重新定義,并由 JavaScript 在適當(dāng)時(shí)間調(diào)用。 toString方法是頻繁重新定義的 Object 方法的一個(gè)示例。
在此語言參考中,每個(gè) Object 方法的說明均包括內(nèi)部 JavaScript 對象的默認(rèn)和對象特定的實(shí)現(xiàn)信息。
IE兼容方面,微軟MSDN文檔的話是”已在 Internet Explorer 6 之前的 Internet Explorer 中引入 Object Object“,所以不用擔(dān)心~
相關(guān)文章
javascript開發(fā)技術(shù)大全 第2章 開始JAVAScript之旅
1st JavaScript Editor ,除了有著色處,還有html標(biāo)簽、屬性、javascript事件、函數(shù),另外還可調(diào)用外部編輯來編輯網(wǎng)頁,也可將常用瀏覽器內(nèi)置在窗口中。2011-07-07推薦JavaScript實(shí)現(xiàn)繼承的最佳方式
本文是介紹了實(shí)用call方法結(jié)合原型鏈方法來實(shí)現(xiàn)javascript繼承的最佳方式,非常的實(shí)用,有需要的小伙伴可以參考下2014-11-11JavaScript排序算法之希爾排序的2個(gè)實(shí)例
希爾排序,也稱遞減增量排序算法,是插入排序的一種高速而穩(wěn)定的改進(jìn)版本。希爾排序是基于插入排序的以下兩點(diǎn)性質(zhì)而提出改進(jìn)方法的2014-04-04JavaScript入門之事件、cookie、定時(shí)等
本文從上一篇文章結(jié)束的地方開始,解釋其他的一些基本的JavaScript語言概念,繼續(xù)為初學(xué)者提供對語言的基礎(chǔ)理解2011-10-10javascript 數(shù)據(jù)類型轉(zhuǎn)換(parseInt,parseFloat)
Number、String函數(shù)是特殊的函數(shù),在JS引擎中,他會自動判斷是作為構(gòu)造函數(shù)調(diào)用還是普通調(diào)用,所以既可以使用new關(guān)鍵字,也可以作為函數(shù)直接調(diào)用。2010-07-07JavaScript 中的日期和時(shí)間及表示標(biāo)準(zhǔn)介紹
本文為大家詳細(xì)介紹下時(shí)間標(biāo)準(zhǔn)指的是什么?UCT和GMT 的概念、關(guān)聯(lián)和區(qū)別?以及時(shí)間表示標(biāo)準(zhǔn)有哪些?感興趣的朋友可以參考下2013-08-08