Object上的一些方法
- assign
- create
- defineProperties
- defineProperty
- keys
- values
- entries
- freeze
- isFrozen
- seal
- isSealed
- getPrototypeOf
- setPrototypeOf
- is
- isExtensible
- preventExtensions
- getOwnPropertyDescriptor
- getOwnPropertyDescriptors
- getOwnPropertySymbols
- getOwnPropertyNames
1.Object.assign(target,source)
將可枚舉屬性的值從一個或對個對象分配到目標對象,返回目標對象
const target = { a: 1, b: 2 }
const source = { b: { b1: 3 }, c: 4 }
const result = Object.assign(target, source)
console.log(result, target);
target.b.b1 = 10
- 可以看出assign是一種
淺拷貝,沒有開闢新的存儲空間去存拷貝來的值,直接的引用
2.Object.create(proto,propertiesObject)
創建一個空對象- 第一個參數作為該對象的
原型 -
第二個參數為該對象的默認屬性
function School(name) { this.name = name } let obj = Object.create(School.prototype, { p: { value: 4, enumerable: false, writable: false, configurable: false }, length: { value: 0 } }) obj.q = 5 obj.p = 5 //writable為false,不可修改 delete obj.p //configurable為false,刪除失敗 for (let i in obj) { console.log(i);//enumerable為false,p不被枚舉 } console.log(obj);- 默認的屬性可以配置屬性,枚舉,可寫,可配置
3.Object.defindeProperty(obj,prop,descriptor)與Object.defineProperties(obj,props)
-
Object.defindeProperty在一個對象上定義或修改一個屬性,返回該對象-
descriptor
- writable 可寫
- enumerable 可枚舉
- configurable 可刪除
- value 值
- get 讀值
- set 設置值
let o = { a: { name: "張三", age: 18, } } var val = null Object.defineProperty(o.a, "rank", { configurable: false, enumerable: true, get() { console.log("獲取張三排名"); return val }, set(newval) { console.log("新值:" + newval); val = newval } }) o.a.rank = 1 console.log(o.a.rank); console.log(o);get set和value writable不能同時使用- 在添加rank值時set會監聽到,可以賦值給一個
中間變量或者該對象上的一個屬性,get會在讀rank時執行 - 點擊rank的
三個點也會監聽到讀的操作
-
-
Object.defineProperties(obj,props)
defineProperty有三個參數,但是隻針對一個屬性
defineProperties的第二個參數不是一個字符串,是一個對象
它將defineProperty的第三個參數融合到第二個參數裏
可以去配置多個屬性let o = { a: { name: "張三", age: 18, } } var val = null let a = Object.defineProperties(o.a, { "rank": { value: 1, }, "grade": { get() { console.log("讀:" + val); return val }, set(newval) { console.log("改" + newval); val = newval } } } ) o.a.grade = 9 console.log(o.a.rank, o.a.grade); console.log(a);- 屬性的相關配置默認均為false
4.Object.getOwnPropertyDescriptor(obj,prop)和Object.getOwnPropertyDescriptors(obj)
獲取指定對象自身屬性的描述符-
一個是獲取
單個,一個獲取全部const o = {} let val = 0 Object.defineProperties(o, { a: { value: 1, enumerable: true, configurable: false, }, b: { configurable: false, enumerable: false, get() { return val }, set(newval) { val = newval } } }) let d1 = Object.getOwnPropertyDescriptor(o, "a") let d2 = Object.getOwnPropertyDescriptors(o) console.log(d1, d2);普通的
追加對象屬性,也會返回相關描述
不過與defineProperty的默認值false正好相反
5.Object.keys(obj) Object.values(obj) Object.entries(obj)
- keys:返回給定對象可枚舉
屬性值組成的數組 - values:返回給定對象可枚舉
屬性名組成的數組 -
entries:返回給定對象可枚舉
鍵值對組成的數組const o = { a: 1, b: 2, fn() { } } for (const k of Object.keys(o)) { console.log(k);//a b fn } for (const v of Object.values(o)) { console.log(v);//1 2 fu(){} } for (const e of Object.entries(o)) { console.log(e);//["a",1] ["b",2] ["fn",fn()] }數組原型上的keys()方法 返回的是Number類型,Object上返回的是字符串
6.freeze(obj) isFrozen()、seal(obj) isSealed()、preventExtensions() isExtensible
- freeze凍結一個對象,不可修改,不可加屬性,不可刪屬性,其原型也不能修改
- seal封閉一個對象,可
修改已有屬性,不可加屬性,不可刪除屬性,原型不可修改 -
preventExtensions不可擴展, 可
刪除,可修改,不可加屬性,原型不可修改const o1 = { a: 1, b: 2, fn() { } } Object.freeze(o1) console.log(Object.isFrozen(o1));//true o1.a = 2 console.log(o1.a);// 1 const o2 = { a: 1, b: 2, fn() { } } Object.seal(o2) console.log(Object.isSealed(o2));//true o2.a = 2 console.log(o2.a);//2 const o3 = { a: 1, b: 2, fn() { } } Object.preventExtensions(o3) console.log(Object.isExtensible(o3));//false o3.a = 2 console.log(delete o3.b);//true console.log(o3.a);//2freeze與seal都
不可擴展且不可刪除,isExtensible的值也為false
7.Object.setPrototypeOf(obj,prototype) Object.getPrototypeOf(obj)
-
設置對象的原型與獲取對象的原型const obj = { name: "obj", getName() { console.log(this.name) } } let o = { name: "o" } Object.setPrototypeOf(o, obj) Object.getPrototypeOf(o).getName()//obj o.getName()//o不建議使用這種方式以及__proto__去修改原型
使用Object.create()來創建一個指定原型的新對象
8.Object.is(value1,value2)
- 判斷兩個值是否為
同一個值
const o1 = {
a: 1
}
const o2 = { b: { c: 2 } }
const o3 = { b: { c: 2 } }
Object.assign(o1, o2)
console.log(Object.is(o1.b, o2.b));//true
console.log(Object.is(o1.b, o3.b));//false
引用的地址不同會檢測出是不同的值
對於原始類型,只要值相同即可
可以看出Object.assign()是淺拷貝,對用引用類型並沒有開闢新的內存空間去存儲,只是複製了棧指針的指向
9.Object.getOwnPropertyNames(obj)和Object.getOwnPropertySymbols(obj)
- getOWnPropertyNames返回指定對象的屬性名組成的
數組,包括不可枚舉的屬性,但不包括Symbol值的屬性名 -
getOwnPropertySymbols返回指定對象所有以Symbol為屬性名的
數組let f = Symbol("foo") const o = { [f]: 1, "a": 2, b: 3 } const n = Object.getOwnPropertyNames(o) const s = Object.getOwnPropertySymbols(o) console.log(n, s);//["a","b"] [Symbol(foo)]
原型上的方法
1.hasOwnProperty
2.isPrototypeOf
3.propertyIsEnumerable
4.toLocalString
5.toString
6.ValueOf
7.__defineGetter__(已廢棄)
8.__defineSetter__(已廢棄)
9.__lookupSetter__(已廢棄)
10.__lookupSetter__(已廢棄)
11.__proto__(屬性 已廢棄)
12.toSource()(非標準)
1.Object.prototype.hasOwnProperty(prop)
-
檢測指定屬性是否有某個屬性,可以檢測到
Symbol類型const a = [1] console.log(a.hasOwnProperty(0));//true let s = Symbol("foo") const o = { [s]: "a", } console.log(o.hasOwnProperty(s));//true
2.Object.prototype.isPrototypeOf(obj)
-
檢測一個對象是否在另一個對象的
原型鏈上function School(name) { this.name = name } School.prototype = { constructor: School, getName() { console.log(this.name); } } function Student(name) { School.call(this, name) } Student.prototype = Object.create(School.prototype) Student.prototype.constructor = Student const std1 = new Student("張三") std1.getName() //張三 console.log(School.prototype.isPrototypeOf(std1));//true上面用
組合寄生的方式實現的繼承
可以檢測出父類的原型在子類實例的原型鏈上
3.Object.prototype.peopertyIsEnumerable(prop)
-
檢測指定對象的某屬性是否
可枚舉let s1 = Symbol("s1") let s2 = Symbol("s2") const o = { [s1]: 0, } Object.defineProperties(o, { [s2]: { value: 1, enumerable: true }, p: { value: 3, } }) console.log(o.propertyIsEnumerable(s1));//true console.log(o.propertyIsEnumerable(s2));//true console.log(o.propertyIsEnumerable("p"));//false
4.toLocalString() toString() valueOf()
- toLocalString返回的是
本地環境字符串,適合處理時間類型 - toString返回
唯一字符串,不會因為環境的改變而變化 - valueOf返回對象的
原始值
統一方法
function transform(o) {
console.log(Object.prototype.toLocaleString.call(o));
console.log(Object.prototype.toString.call(o));
console.log(Object.prototype.valueOf.call(o));
}
基本數據類型
transform(1000)
//"1000" "[object Number]" {1000}
transform(true)
//"true" "[object Boolean]" {true}
transform(Symbol("smb"))
//"Symbol('smb')" "[object Symbol]" {Symbol(smb)}
transform(1000n)
//"1000" "[object BigInt]" {1000n}
transform("str")
//"str" "[object String]" {"str"}
引用數據類型
transform([0, 1])
//"0,1" "[object Array]" [0,1]
transform({ a: 0, b: 1 })
//"[object Object]" "[object Object]" {a:0,b:1}
transform(new Date())
//"標準時間" "[object Date]" "標準時間"
transform(function () { })
//"function () { }" "[object Function]" f () {}
transform(new Error("e"))
// "Error:e" "[object Error]" Error: e
- 可以看出toLocalString返回其內容的
字符串 - toString返回值唯一 都是方括號object + 數據類型的
字符串 - valueOf基本類型會返回一個
對象引用類型返回其本身