摘要:當以非構造函數形式被調用時,等同于。因此只有字符串會以數組形式,拷貝入目標對象,其他值即數值字符串和布爾值都不會產生效果。注意,布爾值數值字符串分別轉成對應的包裝對象時,它們的原始值都在包裝對象的內部屬性上面。擁有布爾值的字段的默認值都是。
Object
Object構造函數創建一個對象包裝器。如果給定值是 null or undefined,將會創建并返回一個空對象,否則,將返回一個與給定值對應類型的對象。布爾值、數值、字符串分別轉成對應的包裝對象時,它們的原始值都在包裝對象的內部屬性[[PrimitiveValue]]上面。只有字符串的包裝對象,會產生可枚舉屬性。
當以非構造函數形式被調用時,Object 等同于 new Object()。
方法 Object.assign()Object.assign(target, ...sources)
target:目標對象。sources:(多個)源對象。
該方法用于將所有可枚舉的屬性的值從一個或多個源對象復制到目標對象。它將返回目標對象。
var o1 = { a: 1 }; var o2 = { b: 2 }; var o3 = { c: 3 }; var obj = Object.assign(o1, o2, o3); console.log(obj); // { a: 1, b: 2, c: 3 } console.log(o1); // { a: 1, b: 2, c: 3 }, 注意目標對象自身也會改變。 obj===o1; //true, obj與o1完全相等
注意:
1.拷貝的屬性為源對象自身的并且可枚舉的(包括Symbol 類型的屬性)。
2.若目標對象與源對象有同名屬性,或多個源對象有同名屬性,則后面的屬性會覆蓋前面的屬性。覆蓋時直接替換。
var target = { a: { b: "c", d: "e" } } var source = { a: { b: "hello" } } Object.assign(target, source) // { a: { b: "hello" } } //target對象的a屬性被source對象的a屬性整個替換掉
3.在屬性拷貝過程中產生異常時,該方法會拋出一個 TypeError 異常,拷貝過程中斷,已經拷貝成功的屬性不會受到影響,還未拷貝的屬性將不會再被拷貝。
4.Object.assign 會跳過那些值為 null 或 undefined 的源對象。
5.Object.assign方法實行的是淺拷貝,而不是深拷貝。 也就是說,如果源對象某個屬性的值是對象,那么目標對象拷貝得到的是這個對象的引用。
var obj1 = {a: {b: 1}}; var obj2 = Object.assign({}, obj1); obj1.a.b = 2; obj2.a.b // 2 //Object.assign拷貝得到的是這個對象的引用。這個對象的任何變化,都會反映到目標對象上面。
6.若參數不是對象,則會先轉成對象。由于undefined和null無法轉成對象,所以當null 和 undefined不在首參數時,會被忽略。在首參數,則報錯。Object.assign不會拷貝對象的內部屬性[[PrimitiveValue]]。因此只有字符串會以數組形式,拷貝入目標對象,其他值(即數值、字符串和布爾值)都不會產生效果。
var v1 = "abc"; var v2 = true; var v3 = 10; var v4 = Symbol("foo") var obj = Object.assign({}, v1, null, v2, undefined, v3, v4); //注意,布爾值、數值、字符串分別轉成對應的包裝對象時,它們的原始值都在包裝對象的內部屬性[[PrimitiveValue]]上面。只有字符串的包裝對象,會產生可枚舉屬性,這些屬性會被拷貝。因此其他類型的值(即數值、字符串和布爾值)不在首參數,除了字符串會以數組形式,拷貝入目標對象,其他值都不會產生效果。 console.log(obj); // { "0": "a", "1": "b", "2": "c" } Object(true) // {[[PrimitiveValue]]: true} Object(10) // {[[PrimitiveValue]]: 10} Object("abc") // {0: "a", 1: "b", 2: "c", length: 3, [[PrimitiveValue]]: "abc"}
7.Object.assign可以用來處理數組,但是會把數組視為對象。
Object.assign([1, 2, 3], [4, 5]) // [4, 5, 3] //Object.assign把數組視為屬性名為0、1、2的對象,因此源數組的0號屬性4覆蓋了目標數組的0號屬性1。
8.拷貝訪問器時,只拷貝其值,訪問器屬性會被轉換成數據屬性。
var obj = { foo: 1, get bar() { return 2; } }; // copy.bar的值來自obj.bar的getter函數的返回值 var copy = Object.assign({}, obj); // { foo: 1, bar: 2 } Object.getOwnPropertyDescriptor(copy,"bar"); //{value: 2, writable: true, enumerable: true, configurable: true} //可以看到bar在obj對象里為存取描述,而在copy對象里面變成了數據描述。
可通過以下代碼進行完整拷貝。該方法為淺拷貝。
Object.create( Object.getPrototypeOf(obj), Object.getOwnPropertyDescriptors(obj) );
var t={ a:{ a1:11, a2:12 }, b:2 }; var c=Object.getOwnPropertyDescriptors(t); var m=Object.create({},c); m.a.a1=333; t.a.a1 //333 //可以看到拷貝時屬性值是淺拷貝Object.create()
Object.create(proto, [ propertiesObject ])
proto:一個對象,應該是新創建的對象的原型,也可以是null。propertiesObject:可選。該參數對象是一組屬性與值,該對象的屬性名稱將是新創建的對象的屬性名稱,值只能是屬性描述符。propertiesObject也可以是undefined。
該方法使用指定的原型對象及其屬性去創建一個新的對象。
// 創建一個以另一個空對象為原型,且擁有一個屬性p的對象 o = Object.create({}, { p: { value: 42 } }) // 省略了的屬性特性默認為false,所以屬性p是不可寫,不可枚舉,不可配置的: o.p = 333 o.p //42
注意:
1.propertiesObject參數對象不能是 null,并且只有該對象中自身擁有的可枚舉的屬性才有效,也就是說該對象的原型鏈上屬性是無效的。
var a={ //foo會成為所創建對象的數據屬性 foo:{ writable:true, configurable:true, value: 222 }, // abc會成為所創建對象的訪問器屬性 abc: { configurable: false, get: function() { return 10 }, set: function(value) { console.log("Setting `o.abc` to", value); } } }; //原型鏈上的屬性不會出現 a.__proto__={ bar:{ writable:true, configurable:true, value: 555, enumerable:true } }; //three屬性可枚舉,因此會出現在o對象中 Object.defineProperty(a,"three",{ value:{ value:333 }, enumerable:true }); //four屬性不可枚舉,因此不會出現在o對象中 Object.defineProperty(a,"four",{ value:{ value:444 }, enumerable:false }) var o = Object.create(Object.prototype,a); o //{foo: 222, three: 333}
2.如果 proto參數不是 null 也不是對象,則拋出一個 TypeError 異常。
Object.defineProperty()Object.defineProperty(obj, prop, descriptor)
obj:需要被操作的目標對象。prop:目標對象需要定義或修改的屬性的名稱。descriptor:將被定義或修改的屬性的描述符。
該方法會直接在一個對象上定義一個新屬性,或者修改一個對象的現有屬性, 并返回這個對象。
對象里目前存在的屬性描述符有兩種主要形式:數據描述符和存取描述符。數據描述符是一個擁有可寫或不可寫值的屬性。存取描述符是由一對 getter-setter 函數功能來描述的屬性。描述符必須是兩種形式之一;不能同時是兩者。
數據描述符的鍵值:configurable,enumerable,value,writable。
存取描述符的鍵值:configurable,enumerable,get,set。
configurable:表示對象的屬性是否可以被刪除,以及除writable和value外的其他特性是否可以被修改。默認為 false。如果一個屬性的 configurable 為 false,則其 writable 特性也只能修改為 false。
var a={}; Object.defineProperty(a,"m", {enumerable:true,configurable:false,value:111,writable:true}); //將enumerable改為false,報錯TypeError: Cannot redefine property: m Object.defineProperty(a,"m", {enumerable:false,configurable:false,value:111,writable:true}); //將writable改為false,成功 Object.defineProperty(a,"m", {enumerable:true,configurable:false,value:111,writable:false}); //再將writable改為true,報錯TypeError: Cannot redefine property: m Object.defineProperty(a,"m", {enumerable:true,configurable:false,value:111,writable:true});
enumerable:表示對象的屬性是否可枚舉。默認為 false。
writable:表示對象的屬性是否能被賦值運算符改變。默認為 false。
注意:
1.當描述符中省略某些字段時,這些字段將使用它們的默認值。擁有布爾值的字段的默認值都是false。value,get和set字段的默認值為undefined。定義屬性時如果沒有get/set/value/writable,那它被歸類為數據描述符。
var o = {}; // 創建一個新對象 Object.defineProperty(o, "a", { enumerable : true, configurable : true }); Object.getOwnPropertyDescriptor(o,"a") //{value: undefined, writable: false, enumerable: true, configurable: true}
2.使用點運算符和Object.defineProperty()為對象的屬性賦值時,數據描述符中的屬性默認值是不同的。
var o = {}; o.a = 1; // 等同于 : Object.defineProperty(o, "a", { value : 1, writable : true, configurable : true, enumerable : true }); // 另一方面, Object.defineProperty(o, "a", { value : 1 }); // 等同于 : Object.defineProperty(o, "a", { value : 1, writable : false, configurable : false, enumerable : false });Object.defineProperties()
Object.defineProperties(obj, props)
obj:將要被添加屬性或修改屬性的對象。props:該對象的一個或多個鍵值對定義了將要為對象添加或修改的屬性的具體配置。
該方法直接在一個對象上定義新的屬性或修改現有屬性,并返回該對象。
var obj = {}; Object.defineProperties(obj, { "property1": { value: true, writable: true }, "property2": { value: "Hello", writable: false } // 等等. }); alert(obj.property2) //彈出"Hello"Object.getOwnPropertyDescriptor()
Object.getOwnPropertyDescriptor(obj, prop)
obj:需要查找的目標對象。prop:目標對象內屬性名稱(String類型)。
該方法返回指定對象上一個自有屬性對應的屬性描述符。(自有屬性指的是直接賦予該對象的屬性,不需要從原型鏈上進行查找的屬性)。即只查找自有屬性。若不存在則返回 undefined。
Object.getOwnPropertyDescriptors()Object.getOwnPropertyDescriptors(obj)
obj:任意對象。
該方法用來獲取一個對象的所有自身屬性的描述符。如果沒有任何自身屬性,則返回空對象。
Object.is()Object.is(value1, value2):確定兩個值是否相同。
Object.is() 會在下面這些情況下認為兩個值是相同的:
兩個值都是 undefined
兩個值都是 null
兩個值都是 true 或者都是 false
兩個值是由相同個數的字符按照相同的順序組成的字符串
兩個值指向同一個對象
兩個值都是數字并且
都是正零 +0
都是負零 -0
都是 NaN
都是除零和 NaN 外的其它同一個數字
Object.is()與嚴格相等運算符 === 不同,“===”會把 -0 和 +0 這兩個數值視為相同的,還會把兩個 NaN 看成是不相等的。
+0 === -0 //true NaN === NaN // false Object.is(+0, -0) // false Object.is(NaN, NaN) // true屬性的遍歷
Object.keys(obj):返回一個數組,成員是參數對象自身的所有可枚舉屬性的鍵名(不含Symbol屬性)。
Object.values(obj):返回一個數組,成員是參數對象自身的所有可枚舉屬性的鍵值(不含Symbol屬性)。
Object.entries(obj):返回一個數組,成員是參數對象自身的所有可枚舉屬性的鍵值對數組(不含Symbol屬性)。該功能為試驗中功能。
for...in:循環遍歷對象自身的和繼承的可枚舉屬性(不含Symbol屬性)。
Object.getOwnPropertyNames(obj):返回一個數組,成員是參數對象自身的可枚舉和不可枚舉屬性的名稱(不含Symbol屬性)。
Object.getOwnPropertySymbols(obj):返回一個數組,成員是參數對象自身的所有symbol屬性的名稱。
Reflect.ownKeys(obj):返回一個數組,成員是參數對象自身的所有屬性的名稱,不管屬性名是Symbol或字符串,也不管是否可枚舉。Reflect.ownKeys的返回值等同于Object.getOwnPropertyNames(obj).concat(Object.getOwnPropertySymbols(obj))。
以上的方法遍歷對象的屬性,都遵守同樣的屬性遍歷的次序規則。
首先遍歷所有屬性名為數值的屬性,按照數字排序。
其次遍歷所有屬性名為字符串的屬性,按照生成時間排序。
最后遍歷所有屬性名為Symbol值的屬性,按照生成時間排序。
原型改變一個對象的 [[Prototype]] 屬性,是一個非常慢且影響性能的操作。推薦使用 Object.create()創建帶有你想要的[[Prototype]]的新對象。
_proto_Object.prototype 的 _proto_ 屬性是一個訪問器屬性??墒褂胈proto_ 進行原型的獲取與設置。但這個是過時且不推薦使用的。使用_proto_ 進行原型的設置時,對象應是可擴展的,不然會拋出一個 TypeError 錯誤。
var a={}; Object.preventExtensions(a); a.__proto__={} //Uncaught TypeError: #Object.getPrototypeOf()
Object.getPrototypeOf(object):返回指定對象的原型(即內部[[Prototype]]屬性的值)。如果沒有繼承屬性,則返回 null 。
Object.setPrototypeOf()Object.setPrototypeOf(obj, prototype):設置一個對象的原型。返回參數對象本身,即obj對象。
若對象是不可擴展的,則會拋出 TypeError異常。如果prototype參數不是一個對象或者null(例如,數字,字符串,boolean,或者 undefined),則什么都不做。否則,該方法將obj的原型修改為新的值。推薦使用該方法來修改對象原型。
如果第一個參數不是對象,會自動轉為對象。但是由于返回的還是第一個參數,所以這個操作不會產生任何效果。由于undefined和null無法轉為對象,所以如果第一個參數是undefined或null,就會報錯。
Object.setPrototypeOf(1, {}) === 1 // true Object.setPrototypeOf(undefined, {}) // TypeError: Object.setPrototypeOf called on null or undefinedObject.prototype.isPrototypeOf()
prototypeObj.isPrototypeOf(object):用于測試prototypeObj對象是否存在于object對象的原型鏈上。如果 prototypeObj 為 undefined 或 null,會拋出 TypeError。
凍結、密封、擴展一個對象默認是可擴展的。
Object.freeze()Object.freeze(obj):凍結一個對象,該方法返回被凍結的對象。凍結對象的屬性不能進行增、刪操作,也不能修改該對象已有屬性的屬性描述符鍵值對。
凍結對象的所有自身屬性都不可能以任何方式被修改,但對該對象原型沒有影響(即仍可對該對象原型上的屬性進行增、刪、改操作)。任何嘗試修改該對象的操作都會失敗,可能是靜默失敗,也可能會拋出異常(嚴格模式中)。
數據屬性的值不可更改,訪問器屬性(有getter和setter)也同樣(但由于是函數調用,給人的錯覺是還是可以修改這個屬性)。
var theValue=0; var t={ get foo(){ return theValue; }, set foo(v){ theValue=v; } } Object.freeze(t); //不能修改foo屬性的get Object.defineProperty(t,"foo",{ get(){ return 222; } }) //TypeError: Cannot redefine property: foo //由于foo是訪問器屬性,所以還是可以修改t.foo的值。 t.foo //0 t.foo=3; t.foo //3
如果一個屬性的值是個對象,則這個對象中的屬性是可以修改的,除非它也是個凍結對象。
obj = { internal : {} }; Object.freeze(obj); obj.internal.a = "aValue"; obj.internal.a // "aValue"
Object.freeze(obj)操作做了兩件事:1.將對象變成不可擴展。2.將對象屬性的configurable和writable變成false。
var a={ m:111, get foo(){ return 333; } }; var before=Object.getOwnPropertyDescriptors(a); Object.freeze(a); var after=Object.getOwnPropertyDescriptors(a);Object.isFrozen()
Object.isFrozen(obj):判斷一個對象是否被凍結。
凍結對象的特征:
不可擴展。
所有自身屬性的configurable為false。
所有自身數據屬性(即無getter和setter的屬性)的writable為false。
在 ES6中, 如果參數不是一個對象類型,則將被視為一個凍結的普通對象,因此會返回 true。但在 ES5 中,會拋出一個 TypeError異常。
Object.isFrozen(1); // TypeError: 1 is not an object (ES5 code) Object.isFrozen(1); // true (ES2015 code)Object.seal()
Object.seal(obj):可以讓一個對象密封,并返回被密封后的對象。密封對象將會阻止向對象添加新的屬性,并且會將所有已有屬性的可配置性(configurable)置為不可配置(false),其效果就是屬性變的不可刪除,以及一個數據屬性不能被重新定義成為訪問器屬性,或者反之。但是可寫性描述(writable)為可寫(true)的屬性的值仍然可被修改。
嘗試刪除一個密封對象的屬性或者將某個密封對象的屬性從數據屬性轉換成訪問器屬性,結果會靜默失敗或拋出TypeError 異常(嚴格模式)。
不會影響從原型鏈上繼承的屬性。但__proto__ 屬性的值也會不能修改。
Object.isSealed()Object.isSealed(obj):判斷一個對象是否被密封。
密封對象的特征:
不可擴展。
所有自身屬性的configurable為false。
在 ES6中, 如果參數不是一個對象類型,則將被視為一個密封的普通對象,因此會返回 true。但在 ES5 中,會拋出一個 TypeError異常。
Object.isSealed(1); // TypeError: 1 is not an object (ES5 code) Object.isSealed(1); // true (ES6 code)Object.preventExtensions()
Object.preventExtensions(obj):讓一個對象變的不可擴展,也就是永遠不能再添加新的屬性,并返回該不可擴展對象。
如果一個對象可以添加新的屬性,則這個對象是可擴展的。preventExtensions只能阻止一個對象不能再添加新的自身屬性,但仍然可以為該對象的原型添加屬性。然而Object.preventExtensions會阻止一個對象將__proto__屬性重新指向另一個對象。
嘗試給一個不可擴展對象添加新屬性的操作將會失敗,不過可能是靜默失敗,也可能會拋出 TypeError 異常(嚴格模式)。在 ECMAScript 5 中可擴展的對象可以變得不可擴展,但反過來不行。
Object.isExtensible()Object.isExtensible(obj):判斷一個對象是否是可擴展的。
在 ES6中, 如果參數不是一個對象類型,則將被視為一個不可擴展的普通對象,因此會返回 true。但在 ES5 中,會拋出一個 TypeError異常。
Object.isExtensible(1); // TypeError: 1 is not an object (ES5 code) Object.isExtensible(1); // false (ES6 code)其他實例方法 Object.prototype.hasOwnProperty()
obj.hasOwnProperty(prop):返回一個布爾值,指示對象是否具有指定的屬性作為自身屬性(即不是從原型鏈上繼承到的屬性)。
prop:要檢測的屬性 字符串名稱或者 Symbol。
object.toString():返回一個表示該對象的字符串。
每個對象都有一個 toString() 方法,當對象被表示為文本值時或者當以期望字符串的方式引用對象時,該方法被自動調用。默認情況下,toString() 方法被每個繼承自Object的對象繼承。如果此方法在自定義對象中未被覆蓋,toString() 返回 "[object type]",其中type是對象類型。
let obj = new Object(); obj.toString(); // 返回 [object Object]
所以可以通過Object.prototype.toString.call(obj)來檢測對象類型。
var toString = Object.prototype.toString; toString.call(new Date); // [object Date] toString.call(new String); // [object String] toString.call(Math); // [object Math] //Since JavaScript 1.8.5 toString.call(undefined); // [object Undefined] toString.call(null); // [object Null]Object.prototype.toLocaleString()
obj.toLocaleString():返回調用 toString() 方法的結果。
Object.prototype.propertyIsEnumerable()obj.propertyIsEnumerable(prop):返回一個布爾值,表明指定的屬性名是否是當前對象可枚舉的自身屬性。
Object.prototype.valueOf()object.valueOf():返回指定對象的原始值。
JavaScript 調用 valueOf() 方法用來把對象轉換成原始類型的值(數值、字符串和布爾值)。 你很少需要自己調用此函數;當遇到一種需要轉換成一個原始值情況時候, JavaScript 會自動調用此函數。
默認情況下, valueOf()會被每個對象Object繼承。每一個內置對象都會覆蓋這個方法為了返回一個合理的值,如果對象沒有原始值,valueOf()就會返回對象自身。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/87391.html
摘要:返回值是一個對象,如果是訪問器屬性,這個對象的屬性有和如果是數據屬性,這個對象的屬性有和。上一篇面向對象版塊之對象屬性下一篇面向對象版塊之創建對象 這是 javascript 面向對象版塊的第三篇文章,主要講解的是多個屬性的定義以及讀取屬性的特性。前面這幾章內容目的在于加深對對象的理解,這樣可以利于理解后面的原型鏈以及繼承方面的知識,或者你也可以了解一下不一樣的 javascript ...
摘要:新增了第七種類型的值數值字符串布爾值對象數據類型判斷有三種方法,可以判斷一個值的類型運算符運算符方法運算符運算符可以返回一個值的數據類型。運算符運算符返回一個布爾值,表示對象是否為某個構造函數的實例。 1.數據類型 JavaScript一共有六種數據類型。(ES6新增了第七種Symbol類型的值) 數值(Number) 字符串(String) 布爾值(boolean) undefin...
介紹 在創建對象的時候,我們有2種常用方法 一個是文本標記法(var obj = {}),一種是運用Object函數進行對象的創建(new Object()). 但是這兩種方式并不是創建的一個完完全全干干凈凈的對象,這里的干凈只得是沒有繼承鏈. 幸運的是,ES5為我們提供了一種創建完全干凈的對象的方法,Object.create函數,接下我將向大家介紹Obje...
摘要:盡管的右操作數是構造函數,但計算過程實際是檢測了對象的繼承關系。通過創建的對象使用構造函數的屬性作為它們的原型。 JavaScript之對象屬性 Object.create()繼承 ECMAScript 5定義了一個名為Object.create()的方法,它創建一個新對象, 其中第一個參數是這個對象的原型。Object.create()提供第二個可選參數,用以對對象的屬性進行進一步描...
摘要:判斷變量類型數據類型種操作符可能返回的值如下注意的能力有限,其對于類型返回的都是使用場景區分對象和原始類型要區分一種對象類型和另一種對象類型可以使用運算符或對象屬性運算符用法左邊的運算數是一個右邊運算數是對象類的名字或者構造函數返回或如果是 判斷變量類型 javaSctipt數據類型7種: Number, String, Boolean, Null, Undefined, Object...
摘要:在最開始的時候,原型對象的設計主要是為了獲取對象的構造函數。同理數組通過調用函數通過調用原型鏈中描述了原型鏈的概念,并將原型鏈作為實現繼承的主要方法。 對象的創建 在JavaScript中創建一個對象有三種方式??梢酝ㄟ^對象直接量、關鍵字new和Object.create()函數來創建對象。 1. 對象直接量 創建對象最直接的方式就是在JavaScript代碼中使用對象直接量。在ES5...
閱讀 2969·2021-11-25 09:43
閱讀 3586·2021-11-24 11:13
閱讀 3354·2021-10-14 09:42
閱讀 2556·2021-09-23 11:53
閱讀 3605·2021-09-22 15:57
閱讀 3221·2021-09-02 09:54
閱讀 3499·2019-08-30 13:47
閱讀 1638·2019-08-29 16:55