Object.assign(target,source1,source2,...)
該方法主要用於對象的合並,將源對象source的所有可枚舉屬性合並到目標對象target上,此方法只拷貝源對象的自身屬性,不拷貝繼承的屬性。
Object.assign方法實行的是淺拷貝,而不是深拷貝。也就是說,如果源對象某個屬性的值是對象,那么目標對象拷貝得到的是這個對象的引用。同名屬性會替換。
Object.assign只能進行值的復制,如果要復制的值是一個取值函數,那么將求值后再復制。
Object.assign可以用來處理數組,但是會把數組視為對象。
const target = {
x : 0,
y : 1
};
const source = {
x : 1,
z : 2 ,
fn : {
number : 1
}
};
Object.assign(target, source);
// target {x : 1, y : 1, z : 2, fn : {number : 1}} // 同名屬性會被覆蓋
// source {x : 1, z : 2, fn : {number : 1}}
target.fn.number = 2; // 拷貝為對象引用
// source {x : 1, z : 2, fn : {number : 2}}
function Person(){
this.name = 1
};
Person.prototype.country = 'china';
let student = new Person();
student.age = 29 ;
const young = {insterst : 'sport'};
Object.assign(young,student);
// young {instest : 'sport' , age : 29, name: 1} // 只能拷貝自身的屬性,不能拷貝prototype
Object.assign([1, 2, 3], [4, 5]) // 把數組當作對象來處理
// [4, 5, 3]
Object.create(prototype[,propertiesObject])
使用指定的原型對象及其屬性去創建一個新的對象
var parent = {
x : 1,
y : 1
}
var child = Object.create(parent,{
z : { // z會成為創建對象的屬性
writable:true,
configurable:true,
value: "newAdd"
}
});
console.log(child)

Object.defineProperties(obj,props)
直接在一個對象上定義新的屬性或修改現有屬性,並返回該對象。
var obj = {};
Object.defineProperties(obj, {
'property1': {
value: true,
writable: true
},
'property2': {
value: 'Hello',
writable: false
}
// etc. etc.
});
console.log(obj) // {property1: true, property2: "Hello"}
Object.defineProperty(obj,prop,descriptor)
在一個對象上定義一個新屬性,或者修改一個對象的現有屬性, 並返回這個對象。
Object.defineProperty(Object, 'is', {
value: function(x, y) {
if (x === y) {
// 針對+0 不等於 -0的情況
return x !== 0 || 1 / x === 1 / y;
}
// 針對NaN的情況
return x !== x && y !== y;
},
configurable: true,
enumerable: false,
writable: true
});
// 注意不能同時設置(writable,value) 和 get,set方法,否則瀏覽器會報錯 : Invalid property descriptor. Cannot both specify accessors and a value or writable attribute
Object.keys(obj)
返回一個由一個給定對象的自身可枚舉屬性組成的數組,數組中屬性名的排列順序和使用 for...in 循環遍歷該對象時返回的順序一致 (兩者的主要區別是 一個 for-in 循環還會枚舉其原型鏈上的屬性)。
let arr = ["a", "b", "c"];
console.log(Object.keys(arr));
// ['0', '1', '2']
/* Object 對象 */
let obj = { foo: "bar", baz: 42 },
keys = Object.keys(obj);
console.log(keys);
// ["foo","baz"]
Object.values()
方法返回一個給定對象自己的所有可枚舉屬性值的數組,值的順序與使用for...in循環的順序相同 ( 區別在於 for-in 循環枚舉原型鏈中的屬性 )。
Object.values會過濾屬性名為 Symbol 值的屬性。
var an_obj = { 100: 'a', 2: 'b', 7: 'c' };
console.log(Object.values(an_obj)); // ['b', 'c', 'a']
var obj = { 0: 'a', 1: 'b', 2: 'c' };
console.log(Object.values(obj)); // ['a', 'b', 'c']
Object.entries()
返回一個給定對象自身可枚舉屬性的鍵值對數組,其排列與使用 for...in 循環遍歷該對象時返回的順序一致(區別在於 for-in 循環也枚舉原型鏈中的屬性)。
const obj = { foo: 'bar', baz: 42 };
console.log(Object.entries(obj)); // [ ['foo', 'bar'], ['baz', 42] ]
const simuArray = { 0: 'a', 1: 'b', 2: 'c' };
console.log(Object.entries(simuArray)); // [ ['0', 'a'], ['1', 'b'], ['2', 'c'] ]
hasOwnProperty()
判斷對象自身屬性中是否具有指定的屬性。
obj.hasOwnProperty('name')
Object.getOwnPropertyDescriptor(obj,prop)
返回指定對象上一個自有屬性對應的屬性描述符。(自有屬性指的是直接賦予該對象的屬性,不需要從原型鏈上進行查找的屬性).
如果指定的屬性存在於對象上,則返回其屬性描述符對象(property descriptor),否則返回 undefined。
var arr = ['name','age'] ;
arr.forEach(val => console.log(Object.getOwnPropertyDescriptor(obj,val)))
// {value: "js", writable: true, enumerable: true, configurable: true}
// undefined
Object.getOwnPropertyDescriptors(obj)
獲取一個對象的所有自身屬性的描述符。
var obj = {
name : 'js',
age : 20
}
console.log(Object.getOwnPropertyDescriptors(obj))


const source = {
set foo(value) {
console.log(value);
}
};
const target2 = {};
Object.defineProperties(target2, Object.getOwnPropertyDescriptors(source));
Object.getOwnPropertyDescriptor(target2, 'foo')
const obj = Object.create(
some_obj,
Object.getOwnPropertyDescriptors({
foo: 123,
})
);
Object.getOwnPropertyNames()
返回一個由指定對象的所有自身屬性的屬性名(包括不可枚舉屬性但不包括Symbol值作為名稱的屬性)組成的數組。
var obj = { 0: "a", 1: "b", 2: "c"};
Object.getOwnPropertyNames(obj).forEach(function(val) {
console.log(val);
});
var obj = {
x : 1,
y : 2
}
Object.defineProperty(obj,'z',{
enumerable : false
})
console.log(Object.getOwnPropertyNames(obj)) // ["x", "y", "z"] 包含不可枚舉屬性 。
console.log(Object.keys(obj)) // ["x", "y"] 只包含可枚舉屬性 。
Object.getOwnPropertySymbols()
返回一個給定對象自身的所有 Symbol 屬性的數組。
Object.getPrototypeOf()
返回指定對象的原型(內部[[Prototype]]屬性的值,即__proto__,而非對象的prototype)。
isPrototypeOf()
判斷一個對象是否存在於另一個對象的原型鏈上。
Object.setPrototypeOf(obj,prototype)
設置對象的原型對象
Object.is()
判斷兩個值是否相同。
如果下列任何一項成立,則兩個值相同:
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.freeze()
凍結一個對象,凍結指的是不能向這個對象添加新的屬性,不能修改其已有屬性的值,不能刪除已有屬性,以及不能修改該對象已有屬性的可枚舉性、可配置性、可寫性。也就是說,這個對象永遠是不可變的。該方法返回被凍結的對象。
var obj = {
prop: function() {},
foo: 'bar'
};
// 新的屬性會被添加, 已存在的屬性可能
// 會被修改或移除
obj.foo = 'baz';
obj.lumpy = 'woof';
delete obj.prop;
// 作為參數傳遞的對象與返回的對象都被凍結
// 所以不必保存返回的對象(因為兩個對象全等)
var o = Object.freeze(obj);
o === obj; // true
Object.isFrozen(obj); // === true
// 現在任何改變都會失效
obj.foo = 'quux'; // 靜默地不做任何事
// 靜默地不添加此屬性
obj.quaxxor = 'the friendly duck';
console.log(obj)
Object.isFrozen()
判斷一個對象是否被凍結 .
Object.preventExtensions()
對象不能再添加新的屬性。可修改,刪除現有屬性,不能添加新屬性。
var obj = {
name :'lilei',
age : 30 ,
sex : 'male'
}
obj = Object.preventExtensions(obj);
console.log(obj); // {name: "lilei", age: 30, sex: "male"}
obj.name = 'haha';
console.log(obj) // {name: "haha", age: 30, sex: "male"}
delete obj.sex ;
console.log(obj); // {name: "haha", age: 30}
obj.address = 'china';
console.log(obj) // {name: "haha", age: 30}
Object.isExtensible()
判斷對象是否是可擴展的,Object.preventExtensions,Object.seal 或 Object.freeze 方法都可以標記一個對象為不可擴展(non-extensible)
Object.seal()
Object.seal() 方法可以讓一個對象密封,並返回被密封后的對象。密封一個對象會讓這個對象變的不能添加新屬性,且所有已有屬性會變的不可配置。屬性不可配置的效果就是屬性變的不可刪除,以及一個數據屬性不能被重新定義成為訪問器屬性,或者反之。但屬性的值仍然可以修改。嘗試刪除一個密封對象的屬性或者將某個密封對象的屬性從數據屬性轉換成訪問器屬性,結果會靜默失敗或拋出TypeError 異常. 不會影響從原型鏈上繼承的屬性。但 __proto__ ( ) 屬性的值也會不能修改。
__proto__ ( ) 屬性的值也會不能修改。
var obj = {
prop: function () {},
foo: "bar"
};
// 可以添加新的屬性,已有屬性的值可以修改,可以刪除
obj.foo = "baz";
obj.lumpy = "woof";
delete obj.prop;
var o = Object.seal(obj);
assert(o === obj);
assert(Object.isSealed(obj) === true);
// 仍然可以修改密封對象上的屬性的值.
obj.foo = "quux";
// 但你不能把一個數據屬性重定義成訪問器屬性.
Object.defineProperty(obj, "foo", { get: function() { return "g"; } }); // 拋出TypeError異常
// 現在,任何屬性值以外的修改操作都會失敗.
obj.quaxxor = "the friendly duck"; // 靜默失敗,新屬性沒有成功添加
delete obj.foo; // 靜默失敗,屬性沒有刪除成功
// ...在嚴格模式中,會拋出TypeError異常
function fail() {
"use strict";
delete obj.foo; // 拋出TypeError異常
obj.sparky = "arf"; // 拋出TypeError異常
}
fail();
// 使用Object.defineProperty方法同樣會拋出異常
Object.defineProperty(obj, "ohai", { value: 17 }); // 拋出TypeError異常
Object.defineProperty(obj, "foo", { value: "eit" }); // 成功將原有值改變
Object.isSealed()
判斷一個對象是否被密封
參考鏈接 : https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object/create
http://es6.ruanyifeng.com/#docs/object
