用於將全部可枚舉屬性的值從一個或多個源對象複製到目標對象。它將返回目標對象。es6
Object.assign(target, ...sources) // target 目標對象。 sources 源對象。數組
'use strict'; let obj1 = { a: 0 , b: { c: 0}}; let obj2 = Object.assign({}, obj1); console.log(JSON.stringify(obj2)); // { a: 0, b: { c: 0}} obj1.a = 1; console.log(JSON.stringify(obj1)); // { a: 1, b: { c: 0}} console.log(JSON.stringify(obj2)); // { a: 0, b: { c: 0}} obj2.a = 2; console.log(JSON.stringify(obj1)); // { a: 1, b: { c: 0}} console.log(JSON.stringify(obj2)); // { a: 2, b: { c: 0}} obj2.b.c = 3; console.log(JSON.stringify(obj1)); // { a: 1, b: { c: 3}} console.log(JSON.stringify(obj2)); // { a: 2, b: { c: 3}} // Deep Clone obj1 = { a: 0 , b: { c: 0}}; let obj3 = JSON.parse(JSON.stringify(obj1)); obj1.a = 4; obj1.b.c = 4; console.log(JSON.stringify(obj3)); // { a: 0, b: { c: 0}} //合併對象 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 }, 注意目標對象自身也會改變。 //合併具備相同屬性的對象 var o1 = { a: 1, b: 1, c: 1 }; var o2 = { b: 2, c: 2 }; var o3 = { c: 3 }; var obj = Object.assign({}, o1, o2, o3); console.log(obj); // { a: 1, b: 2, c: 3 } //拷貝 symbol 類型的屬性 var o1 = { a: 1 }; var o2 = { [Symbol('foo')]: 2 }; var obj = Object.assign({}, o1, o2); console.log(obj); // { a : 1, [Symbol("foo")]: 2 } (cf. bug 1207182 on Firefox) Object.getOwnPropertySymbols(obj); // [Symbol(foo)] //繼承屬性和不可枚舉屬性是不能拷貝的 var obj = Object.create({foo: 1}, { // foo 是個繼承屬性。 bar: { value: 2 // bar 是個不可枚舉屬性。 }, baz: { value: 3, enumerable: true // baz 是個自身可枚舉屬性。 } }); var copy = Object.assign({}, obj); console.log(copy); // { baz: 3 } // 原始類型會被包裝爲對象 var v1 = "abc"; var v2 = true; var v3 = 10; var v4 = Symbol("foo") var obj = Object.assign({}, v1, null, v2, undefined, v3, v4); // 原始類型會被包裝,null 和 undefined 會被忽略。 // 注意,只有字符串的包裝對象纔可能有自身可枚舉屬性。 console.log(obj); // { "0": "a", "1": "b", "2": "c" }
建立一個新對象,使用現有的對象來提供新建立的對象的__proto__。dom
Object.create(proto, [propertiesObject])函數
新建立對象的原型對象。this
可選。若是沒有指定爲 undefined,則是要添加到新建立對象的可枚舉屬性(即其自身定義的屬性,而不是其原型鏈上的枚舉屬性)對象的屬性描述符以及相應的屬性名稱。這些屬性對應Object.defineProperties()的第二個參數。spa
//用 Object.create實現類式繼承 // Shape - 父類(superclass) function Shape() { this.x = 0; this.y = 0; } // 父類的方法 Shape.prototype.move = function(x, y) { this.x += x; this.y += y; console.info('Shape moved.'); }; // Rectangle - 子類(subclass) function Rectangle() { Shape.call(this); // call super constructor. } // 子類續承父類 Rectangle.prototype = Object.create(Shape.prototype); Rectangle.prototype.constructor = Rectangle; var rect = new Rectangle(); console.log('Is rect an instance of Rectangle?', rect instanceof Rectangle); // true console.log('Is rect an instance of Shape?', rect instanceof Shape); // true rect.move(1, 1); // Outputs, 'Shape moved.' //使用 Object.create 的 propertyObject參數 var o; // 建立一個原型爲null的空對象 o = Object.create(null); o = {}; // 以字面量方式建立的空對象就至關於: o = Object.create(Object.prototype); o = Object.create(Object.prototype, { // foo會成爲所建立對象的數據屬性 foo: { writable:true, configurable:true, value: "hello" }, // bar會成爲所建立對象的訪問器屬性 bar: { configurable: false, get: function() { return 10 }, set: function(value) { console.log("Setting `o.bar` to", value); } } }); function Constructor(){} o = new Constructor(); // 上面的一句就至關於: o = Object.create(Constructor.prototype); // 固然,若是在Constructor函數中有一些初始化代碼,Object.create不能執行那些代碼 // 建立一個以另外一個空對象爲原型,且擁有一個屬性p的對象 o = Object.create({}, { p: { value: 42 } }) // 省略了的屬性特性默認爲false,因此屬性p是不可寫,不可枚舉,不可配置的: o.p = 24 o.p //42 o.q = 12 for (var prop in o) { console.log(prop) } //"q" delete o.p //false //建立一個可寫的,可枚舉的,可配置的屬性p o2 = Object.create({}, { p: { value: 42, writable: true, enumerable: true, configurable: true } });
直接在一個對象上定義新的屬性或修改現有屬性,並返回該對象。prototype
configurable enumerable value writable get set 數據描述符 Yes Yes Yes Yes No No 存取描述符 Yes Yes No No Yes Yes
// 顯式 Object.defineProperty(obj, "key", { enumerable: false, configurable: false, writable: false, value: "static" }); var obj = {}; Object.defineProperties(obj, { 'property1': { value: true, writable: true }, 'property2': { value: 'Hello', writable: false } // etc. etc. });
返回一個給定對象自身可枚舉屬性的鍵值對數組,其排列與使用 for...in 循環遍歷該對象時返回的順序一致(區別在於 for-in 循環也枚舉原型鏈中的屬性)。code
Object.entries(obj)
const obj = { foo: 'bar', baz: 42 }; console.log(Object.entries(obj)); // [ ['foo', 'bar'], ['baz', 42] ] // array like object const obj = { 0: 'a', 1: 'b', 2: 'c' }; console.log(Object.entries(obj)); // [ ['0', 'a'], ['1', 'b'], ['2', 'c'] ] // array like object with random key ordering const anObj = { 100: 'a', 2: 'b', 7: 'c' }; console.log(Object.entries(anObj)); // [ ['2', 'b'], ['7', 'c'], ['100', 'a'] ] // getFoo is property which isn't enumerable const myObj = Object.create({}, { getFoo: { value() { return this.foo; } } }); myObj.foo = 'bar'; console.log(Object.entries(myObj)); // [ ['foo', 'bar'] ] // non-object argument will be coerced to an object console.log(Object.entries('foo')); // [ ['0', 'f'], ['1', 'o'], ['2', 'o'] ] // iterate through key-value gracefully const obj = { a: 5, b: 7, c: 9 }; for (const [key, value] of Object.entries(obj)) { console.log(`${key} ${value}`); // "a 5", "b 7", "c 9" } // Or, using array extras Object.entries(obj).forEach(([key, value]) => { console.log(`${key} ${value}`); // "a 5", "b 7", "c 9" }); // 將Object轉換爲Map var obj = { foo: "bar", baz: 42 }; var map = new Map(Object.entries(obj)); console.log(map); // Map { foo: "bar", baz: 42 }
能夠凍結一個對象,凍結指的是不能向這個對象添加新的屬性,不能修改其已有屬性的值,不能刪除已有屬性,以及不能修改該對象已有屬性的可枚舉性、可配置性、可寫性。也就是說,這個對象永遠是不可變的。該方法返回被凍結的對象。對象
const object1 = { property1: 42 }; const object2 = Object.freeze(object1); object2.property1 = 33; // Throws an error in strict mode console.log(object2.property1); // expected output: 42 // 凍結數組 let a = [0]; Object.freeze(a); // The array cannot be modified now.
判斷對象是否已經凍結。繼承
// 一個對象默認是可擴展的,因此它也是非凍結的. Object.isFrozen({}); // === false // 一個不可擴展的空對象同時也是一個凍結對象. var vacuouslyFrozen = Object.preventExtensions({}); Object.isFrozen(vacuouslyFrozen) //=== true; // 一個非空對象默認也是非凍結的. var oneProp = { p: 42 }; Object.isFrozen(oneProp) //=== false // 讓這個對象變的不可擴展,並不意味着這個對象變成了凍結對象, // 由於p屬性仍然是能夠配置的(並且可寫的). Object.preventExtensions(oneProp); Object.isFrozen(oneProp) //=== false // ...若是刪除了這個屬性,則它會成爲一個凍結對象. delete oneProp.p; Object.isFrozen(oneProp) //=== true
返回指定對象上一個自有屬性對應的屬性描述符。(自有屬性指的是直接賦予該對象的屬性,不須要從原型鏈上進行查找的屬性)
Object.getOwnPropertyDescriptor(obj, prop) //obj 須要查找的目標對象 prop 目標對象內屬性名稱(String類型)
var o, d; o = { get foo() { return 17; } }; d = Object.getOwnPropertyDescriptor(o, "foo"); // d { // configurable: true, // enumerable: true, // get: /*the getter function*/, // set: undefined // } o = { bar: 42 }; d = Object.getOwnPropertyDescriptor(o, "bar"); // d { // configurable: true, // enumerable: true, // value: 42, // writable: true // } o = {}; Object.defineProperty(o, "baz", { value: 8675309, writable: false, enumerable: false }); d = Object.getOwnPropertyDescriptor(o, "baz"); // d { // value: 8675309, // writable: false, // enumerable: false, // configurable: false // }
返回一個由指定對象的全部自身屬性
的屬性名(包括不可枚舉屬性但不包括Symbol值做爲名稱的屬性)組成的數組。
// 使用Array.forEach輸出屬性名和屬性值 Object.getOwnPropertyNames(obj).forEach(function(val, idx, array) { console.log(val + " -> " + obj[val]); }); //不可枚舉屬性 var my_obj = Object.create({}, { getFoo: { value: function() { return this.foo; }, enumerable: false } }); my_obj.foo = 1; console.log(Object.getOwnPropertyNames(my_obj).sort()); // ["foo", "getFoo"] //該方法不會獲取到原型鏈上的屬性 function ParentClass() {} ParentClass.prototype.inheritedMethod = function() {}; function ChildClass() { this.prop = 5; this.method = function() {}; } ChildClass.prototype = new ParentClass; ChildClass.prototype.prototypeMethod = function() {}; console.log( Object.getOwnPropertyNames( new ChildClass() // ["prop", "method"] ) );
返回指定對象的原型(內部[[Prototype]]屬的值)
var proto = {}; var obj = Object.create(proto); Object.getPrototypeOf(obj) === proto; // true var reg = /a/; Object.getPrototypeOf(reg) === RegExp.prototype; // true
判斷兩個值是不是相同的值。
Object.is('foo', 'foo'); // true Object.is(window, window); // true Object.is('foo', 'bar'); // false Object.is([], []); // false var test = { a: 1 }; Object.is(test, test); // true Object.is(null, null); // true // 特例 Object.is(0, -0); // false Object.is(-0, -0); // true Object.is(NaN, 0/0); // true
讓一個對象變的不可擴展,也就是永遠不能再添加新的屬性。
// Object.preventExtensions將原對象變的不可擴展,而且返回原對象. var obj = {}; var obj2 = Object.preventExtensions(obj); obj === obj2; // true // 字面量方式定義的對象默認是可擴展的. var empty = {}; Object.isExtensible(empty) //=== true // ...但能夠改變. Object.preventExtensions(empty); Object.isExtensible(empty) //=== false // 使用Object.defineProperty方法爲一個不可擴展的對象添加新屬性會拋出異常. var nonExtensible = { removable: true }; Object.preventExtensions(nonExtensible); Object.defineProperty(nonExtensible, "new", { value: 8675309 }); // 拋出TypeError異常 // 在嚴格模式中,爲一個不可擴展對象的新屬性賦值會拋出TypeError異常. function fail() { "use strict"; nonExtensible.newProperty = "FAIL"; // throws a TypeError } fail(); // 一個不可擴展對象的原型是不可更改的,__proto__是個非標準魔法屬性,能夠更改一個對象的原型. var fixed = Object.preventExtensions({}); fixed.__proto__ = { oh: "hai" }; // 拋出TypeError異常
判斷一個對象是不是可擴展的(是否能夠在它上面添加新的屬性)。
默認狀況下,對象是可擴展的:便可覺得他們添加新的屬性。以及它們的 proto 屬性能夠被更改。Object.preventExtensions,Object.seal 或 Object.freeze 方法均可以標記一個對象爲不可擴展(non-extensible)。
// 新對象默認是可擴展的. var empty = {}; Object.isExtensible(empty); // === true // ...能夠變的不可擴展. Object.preventExtensions(empty); Object.isExtensible(empty); // === false // 密封對象是不可擴展的. var sealed = Object.seal({}); Object.isExtensible(sealed); // === false // 凍結對象也是不可擴展. var frozen = Object.freeze({}); Object.isExtensible(frozen); // === false
封閉一個對象,阻止添加新屬性並將全部現有屬性標記爲不可配置。當前屬性的值只要可寫就能夠改變。
var obj = { prop: function() {}, foo: 'bar' }; // New properties may be added, existing properties // may be changed or removed. obj.foo = 'baz'; obj.lumpy = 'woof'; delete obj.prop; var o = Object.seal(obj); o === obj; // true Object.isSealed(obj); // === true // Changing property values on a sealed object // still works. obj.foo = 'quux'; // But you can't convert data properties to accessors, // or vice versa. Object.defineProperty(obj, 'foo', { get: function() { return 'g'; } }); // throws a TypeError // Now any changes, other than to property values, // will fail. obj.quaxxor = 'the friendly duck'; // silently doesn't add the property delete obj.foo; // silently doesn't delete the property // ...and in strict mode such attempts // will throw TypeErrors. function fail() { 'use strict'; delete obj.foo; // throws a TypeError obj.sparky = 'arf'; // throws a TypeError } fail(); // Attempted additions through // Object.defineProperty will also throw. Object.defineProperty(obj, 'ohai', { value: 17 }); // throws a TypeError Object.defineProperty(obj, 'foo', { value: 'eit' }); // changes existing property value
判斷一個對象是否被密封。
// 新建的對象默認不是密封的. var empty = {}; Object.isSealed(empty); // === false // 若是你把一個空對象變的不可擴展,則它同時也會變成個密封對象. Object.preventExtensions(empty); Object.isSealed(empty); // === true // 但若是這個對象不是空對象,則它不會變成密封對象,由於密封對象的全部自身屬性必須是不可配置的. var hasProp = { fee: "fie foe fum" }; Object.preventExtensions(hasProp); Object.isSealed(hasProp); // === false // 若是把這個屬性變的不可配置,則這個對象也就成了密封對象. Object.defineProperty(hasProp, "fee", { configurable: false }); Object.isSealed(hasProp); // === true // 最簡單的方法來生成一個密封對象,固然是使用Object.seal. var sealed = {}; Object.seal(sealed); Object.isSealed(sealed); // === true // 一個密封對象同時也是不可擴展的. Object.isExtensible(sealed); // === false // 一個密封對象也能夠是一個凍結對象,但不是必須的. Object.isFrozen(sealed); // === true ,全部的屬性都是不可寫的 var s2 = Object.seal({ p: 3 }); Object.isFrozen(s2); // === false, 屬性"p"可寫 var s3 = Object.seal({ get p() { return 0; } }); Object.isFrozen(s3); // === true ,訪問器屬性不考慮可寫不可寫,只考慮是否可配置
返回一個由一個給定對象的自身可枚舉屬性組成的數組,數組中屬性名的排列順序和使用 for...in 循環遍歷該對象時返回的順序一致 。
// simple array var arr = ['a', 'b', 'c']; console.log(Object.keys(arr)); // console: ['0', '1', '2'] // array like object var obj = { 0: 'a', 1: 'b', 2: 'c' }; console.log(Object.keys(obj)); // console: ['0', '1', '2'] // array like object with random key ordering var anObj = { 100: 'a', 2: 'b', 7: 'c' }; console.log(Object.keys(anObj)); // console: ['2', '7', '100'] // getFoo is a property which isn't enumerable var myObj = Object.create({}, { getFoo: { value: function () { return this.foo; } } }); myObj.foo = 1; console.log(Object.keys(myObj)); // console: ['foo']
返回一個給定對象本身的全部可枚舉屬性值的數組,值的順序與使用for...in循環的順序相同 ( 區別在於 for-in 循環枚舉原型鏈中的屬性 )。
var obj = { foo: 'bar', baz: 42 }; console.log(Object.values(obj)); // ['bar', 42] // array like object var obj = { 0: 'a', 1: 'b', 2: 'c' }; console.log(Object.values(obj)); // ['a', 'b', 'c'] // array like object with random key ordering // when we use numeric keys, the value returned in a numerical order according to the keys var an_obj = { 100: 'a', 2: 'b', 7: 'c' }; console.log(Object.values(an_obj)); // ['b', 'c', 'a'] // getFoo is property which isn't enumerable var my_obj = Object.create({}, { getFoo: { value: function() { return this.foo; } } }); my_obj.foo = 'bar'; console.log(Object.values(my_obj)); // ['bar'] // non-object argument will be coerced to an object console.log(Object.values('foo')); // ['f', 'o', 'o']
設置一個指定的對象的原型 ( 即, 內部[[Prototype]]屬性)到另外一個對象或 null
var dict = Object.setPrototypeOf({}, null);