JavaScript筆記,讀《JavaScript權威指南》筆記(三)--對象

 2023-11-18 阅读 21 评论 0

摘要:1.對象介紹 JavaScript筆記。對象是JavaScript的基本數據類型。對象是一種復合值:它將很多值(原始值或者其他對象)聚合在一起,可通過名字訪問這些值。對象也可看做是屬性的無序集合,每個屬性都是一個名/值對。屬性名是字符串,因此我

1.對象介紹

JavaScript筆記。對象是JavaScript的基本數據類型。對象是一種復合值:它將很多值(原始值或者其他對象)聚合在一起,可通過名字訪問這些值。對象也可看做是屬性的無序集合,每個屬性都是一個名/值對。屬性名是字符串,因此我們可以把對象看成是從字符串到值的映射。
由于JavaScript是弱類型語言,因此不必遵循這條規定,在任何對象中程序都可以創建任意數量的屬性。除了字符串、數字、true、false、null和undefined之外,JavaScript中的值都是對象。

2.對象屬性的操作

http權威指南怎么樣,1)對象對于點(.)來說,右側必須是一個以屬性名稱命名的簡單標識符。對于方括號來說([]),方括號內必須是一個計算結果為字符串的表達式,這個字符串就是屬性的名字

2)使用方括號和一個字符串,看起來更像數組,只是這個數組元素是通過字符串索引而不是數字索引。這種數組就是我們所說的關聯數組,也稱做散列、映射或字典JavaScript對象都是關聯數組

3)由于在寫程序的時候不知道屬性名稱,因此無法通過點運算符(.)來訪問對象portfolio的屬性。但可以使用[]運算符,因為它使用字符串值(字符串值是動態的,可以在運行時更改)而不是標識符(標識符是靜態的,必須寫死在程序中)作為索引對屬性進行訪問。

4)delete運算符只能刪除自有屬性,不能刪除繼承屬性

5)在這些場景下給對象o設置屬性p會失敗:

  • o中的屬性p是只讀的:不能給只讀屬性重新賦值(defineProperty()方法中有一個例外,可以對可配置的只讀屬性重新賦值)。
  • o中的屬性p是繼承屬性,且它是只讀的:不能通過同名自有屬性覆蓋只讀的繼承屬性。
  • o中不存在自有屬性p:o沒有使用setter方法繼承屬性p,并且o的可擴展性(extensible attribute)是false(參照6.8.3節)。如果o中不存在p,而且沒有setter方法可供調用,則p一定會添加至o中。但如果o不是可擴展的,那么在o中不能定義新屬性。

6)屬性賦值要么失敗,要么創建一個屬性,要么在原始對象中設置屬性,但有一個例外,如果o繼承自屬性x,而這個屬性是一個具有setter方法的accessor屬性,那么這時將調用setter方法而不是給o創建一個屬性x。需要注意的是,setter方法是由對象o調用的,而不是定義這個屬性的原型對象調用的。因此如果setter方法定義任意屬性,這個操作只是針對o本身,并不會修改原型鏈。

var unitcircle = { r:1 };      // 一個用來繼承的對象
var c = inherit(unitcircle); // c繼承屬性r
c.x = 1; c.y = 1;              // c定義兩個屬性
c.r = 2;                       // c覆蓋繼承來的屬性
unitcircle.r;                  // => 1,原型對象沒有修改

3.對象的繼承

假設要查詢對象o的屬性x,如果o中不存在x,那么將會繼續在o的原型對象中查詢屬性x。如果原型對象中也沒有x,但這個原型對象也有原型,那么繼續在這個原型對象的原型上執行查詢,直到找到x或者查找到一個原型是null的對象為止。可以看到,對象的原型屬性構成了一個“鏈”,通過這個“鏈”可以實現屬性的繼承。

現在假設給對象o的屬性x賦值,如果o中已經有屬性x(這個屬性不是繼承來的),那么這個賦值操作只改變這個已有屬性x的值。如果o中不存在屬性x,那么賦值操作給o添加一個新屬性x。如果之前o繼承自屬性x,那么這個繼承的屬性就被新創建的同名屬性覆蓋了。屬性賦值操作首先檢查原型鏈,以此判定是否允許賦值操作。例如,如果o繼承自一個只讀屬性x,那么賦值操作是不允許的。如果允許屬性賦值操作,它也總是在原始對象上創建屬性或對已有的屬性賦值,而不會去修改原型鏈。在JavaScript中,只有在查詢屬性時才會體會到繼承的存在,而設置屬性則和繼承無關,這是JavaScript的一個重要特性,該特性讓程序員可以有選擇地覆蓋(override)繼承的屬性。

4.循環對象

  • for/in循環對象的可枚舉的屬性,包括自身和繼承的屬性;
  • Object.keys()它返回一個數組,這個數組由對象中可枚舉的自有屬性的名稱組成;
  • Object.getOwnPropertyNames(),它和Ojbect.keys()類似,只是它返回對象的所有自有屬性的名稱,而不僅僅是可枚舉的屬性

5.判斷某個屬性是否存在于某個對象中

判斷某個屬性是否存在于某個對象中。可以通過in運算符、hasOwnPreperty()和propertyIsEnumerable()方法來完成這個工作,甚至僅通過屬性查詢也可以做到這一點。

1)in運算符的左側是屬性名(字符串),右側是對象。如果對象的自有屬性或繼承屬性中包含這個屬性則返回true:

var o = { x: 1 }
"x" in o;             // true:"x"是o的屬性
"y" in o;             // false:"y"不是o的屬性
"toString" in o;      // true:o繼承toString屬性

2)對象的hasOwnProperty()方法用來檢測給定的名字是否是對象的自有屬性。對于繼承屬性它將返回false:

var o = { x: 1 }
o.hasOwnProperty("x"); // true:o有一個自有屬性x
o.hasOwnProperty("y"); // false:o中不存在屬性y
o.hasOwnProperty("toString"); // false:toString是繼承屬性

3)propertyIsEnumerable()是hasOwnProperty()的增強版,只有檢測到是自有屬性且這個屬性的可枚舉性(enumerable attribute)為true時它才返回true。某些內置屬性是不可枚舉的。通常由JavaScript代碼創建的屬性都是可枚舉的

4)另一種更簡便的方法是使用“!==”判斷一個屬性是否是undefined

var o = { x: 1 }
o.x !== undefined; //true: o中有屬性x
o.y !== undefined; // false: o中沒有屬性y
o.toString !== undefined; //true: o繼承了toString屬性

6.getter和setter

當程序查詢存取器屬性的值時,JavaScript調用getter方法(無參數)。這個方法的返回值就是屬性存取表達式的值。當程序設置一個存取器屬性的值時,JavaScript調用setter方法,將賦值表達式右側的值當做參數傳入setter。從某種意義上講,這個方法負責“設置”屬性值。可以忽略setter方法的返回值。

我們將存取器屬性的getter和setter方法看成是屬性的特性。按照這個邏輯,我們也可以把數據屬性的值同樣看做屬性的特性。因此,可以認為一個屬性包含一個名字和4個特性。數據屬性的4個特性分別是它的值(value)、可寫性(writable)、可枚舉性(enumerable)和可配置性(configurable)。存取器屬性不具有值(value)特性和可寫性,它們的可寫性是由setter方法存在與否決定的。因此存取器屬性的4個特性是讀取(get)、寫入(set)、可枚舉性和可配置性。

var o = {// 普通的數據屬性
    data_prop: value,// 存取器屬性都是成對定義的函數get accessor_prop(){ /*這里是函數體 */ },set accessor_prop(value){ /* 這里是函數體*/ }
};

?7. 其他

01 isPrototypeOf() 檢測一個對象是否是另一個對象的原型(或處于原型中)

object1.isPrototypeOf(object2);
判斷指定對象object1是否存在于另一個對象object2的原型鏈中

var a = {b : 1};
Object.prototype.isPrototypeOf(a) // true

02?hasOwnProperty()方法用來檢測給定的名字是否是對象的自有屬性

03?propertyIsEnumerable()檢測到是自有屬性且這個屬性的可枚舉性

04 toString()講對象轉成字符串,沒有參數,返回"[object Object]"

05 valueOf() 講對象轉成某種原始值而非字符串

06?Object.getPropertyOf(obj)是用來得到obj對象的原型對象的標準方法

07 Object.create()創建對象

08??Object.keys()它返回一個數組,這個數組由對象中可枚舉的自有屬性的名稱組成;

09? Object.values()它返回一個數組,這個數組由對象中可枚舉的自有屬性的值組成;

10 Object.entries()返回一個數組,成員是參數對象可枚舉的自有屬性的鍵值對數組。

var a = {b: 1, bb: 2}
Object.entries(a) // [["b", 1],["bb", 2]]

11 Object.assign()用于將所有可枚舉屬性的值從一個或多個源對象復制到目標對象。它將返回目標對象。

var a = {b: 1};
Object.assign(a, {bb: 2}, {bbb: 3}) // {b: 1, bb: 2, bbb: 3}

12 Object.getOwnPropertyNames(),它和Ojbect.keys()類似,只是它返回對象的所有自有屬性的名稱,而不僅僅是可枚舉的屬性

13 Object.getOwnPropertyDescriptors()返回某個對象屬性的描述對象;?

var a = {b: 1};
Object.getOwnPropertyDescriptors(a)
// b: {value: 1, writable: true, enumerable: true, configurable: true}

14?Object.defineProperty(obj, prop, descriptor) 會直接在一個對象上定義一個新屬性,或者修改一個對象的現有屬性, 并返回這個對象。如果不指定configurable, writable, enumerable ,則這些屬性默認值為false,如果不指定value, get, set,則這些屬性默認值為undefined

var obj = {};
Object.defineProperty(obj, 'name', {configurable: false,writable: true,enumerable: true,value: '張三'
})

15?Object.defineProperties()接在一個對象上定義一個或多個新的屬性或修改現有屬性,并返回該對象。

16?Object.is()是用來比較兩個值是否嚴格相等的方法,與===的行為基本一致,與===的區別:01 Object.is(+0, -0) // false; 02?Object.is(NaN, NaN) // true

17?Object.preventExtensions() 讓一個對象變的不可擴展,也就是永遠不能再添加新的屬性。Object.isExtensible()判斷一個對象是否是可擴展

18?Object.seal() 讓一個對象密封,并返回被密封后的對象。密封對象是指那些不能添加新的屬性,不能刪除已有屬性,以及不能修改已有屬性的可枚舉性、可配置性、可寫性,但可能可以修改已有屬性的值的對象。Object.isSealed() 判斷一個對象是否是密封的

19?Object.freeze()凍結一個對象并返回被凍結的對象。凍結對象是指那些不能添加新的屬性,不能修改已有屬性的值,不能刪除已有屬性,以及不能修改已有屬性的可枚舉性、可配置性、可寫性的對象。也就是說,這個對象永遠是不可變的。Object.isFrozen()判斷一個對象是否被凍結

?

轉載于:https://www.cnblogs.com/bear-blogs/p/10448115.html

版权声明:本站所有资料均为网友推荐收集整理而来,仅供学习和研究交流使用。

原文链接:https://hbdhgg.com/5/173946.html

发表评论:

本站为非赢利网站,部分文章来源或改编自互联网及其他公众平台,主要目的在于分享信息,版权归原作者所有,内容仅供读者参考,如有侵权请联系我们删除!

Copyright © 2022 匯編語言學習筆記 Inc. 保留所有权利。

底部版权信息