摘要:一切對(duì)象都是的實(shí)例,一切函數(shù)都是的實(shí)例,是構(gòu)造函數(shù),函數(shù)是的實(shí)例,是對(duì)象,對(duì)象是的實(shí)例,可以說(shuō)與是一對(duì)密不可分的兄弟,讓我們一起解開與的神秘面紗,本章主要了解相關(guān)知識(shí),下章再來(lái)看構(gòu)造函數(shù)可以創(chuàng)建一個(gè)對(duì)象包裝器中所有對(duì)象都來(lái)自所有對(duì)象從繼承方
一切對(duì)象都是 Object 的實(shí)例,一切函數(shù)都是 Function 的實(shí)例,Object 是構(gòu)造函數(shù),函數(shù)是 Function 的實(shí)例,F(xiàn)unction.prototype 是對(duì)象,對(duì)象是 Object 的實(shí)例,可以說(shuō) Object 與 Function 是一對(duì)密不可分的兄弟,讓我們一起解開 Object 與 Function 的神秘面紗,本章主要了解 Object 相關(guān)知識(shí),下章再來(lái)看 Function
Function instanceof Object // true Object instanceof Function // true
Object 構(gòu)造函數(shù)可以創(chuàng)建一個(gè)對(duì)象包裝器
JS 中所有對(duì)象都來(lái)自 Object, 所有對(duì)象從 Object.prototype 繼承方法和屬性
傳入的值為 null 或 undefined 將返回一個(gè) {} 空對(duì)象
Object(null) // {} Object(undefined) // {}
Object() 等同于 new Object()
對(duì)象字面量由 {} 包含零個(gè)或多個(gè)鍵值對(duì)組成以逗號(hào)分隔的列表構(gòu)成
對(duì)象字面量是屬性名及其關(guān)聯(lián)值的集合
必須由 逗號(hào) 分隔
下面是 ES6(ECMAScript 2015) 中對(duì)象的定義方式
const a = 1; var obj = { a, get a(){}, set a(){}, ["a" + "b"]: "hello", say(){}, baz: { b: 2 } }重復(fù)屬性
重復(fù)的屬性,后面的屬性會(huì)覆蓋前面的屬性,在ES5中,重復(fù)的屬性會(huì)拋出語(yǔ)法錯(cuò)誤 SyntaxError
對(duì)象合并Object.assign() 可以合并兩個(gè)對(duì)象,也可以使用展開符 ... 合并兩個(gè)對(duì)象,Object.assign() 會(huì)觸發(fā) setter,而展開操作符則不會(huì)
var a = { a: 1 }; var b = { b: 2 }; var mergedObj = Object.assign({}, a, b) var mergedObj = { ...a, ...b }變更對(duì)象原型
如果給對(duì)象的 _proto_ 賦值為 null, 則會(huì)更改對(duì)象原型,賦值為其它任何值則不會(huì)改變對(duì)象原型
Object.getPrototypeOf({__proto__:null}) === null // true Object.getPrototypeOf({__proto__:{}}) === null // false
在對(duì)象字面值中,只有一次改變?cè)偷臋C(jī)會(huì),多次變更會(huì)報(bào)語(yǔ)法錯(cuò)誤
不使用 : 定義 _proto__ 不會(huì)變更原型,而是會(huì)變成對(duì)象的普通屬性
var __proto__ = "variable"; var obj1 = { __proto__ }; Object.getPrototypeOf(obj1) === Object.prototype // true var obj2 = { __proto__() { return "hello"; } }; obj2.__proto__() === "與JSON區(qū)別
對(duì)象字面量 與 JSON(JavaScript Object Notation) 的區(qū)別
JSON 只允許 以 "property": value 的形式定義屬性,且屬性名必須以 " 號(hào)括起來(lái),屬性定義不允許簡(jiǎn)寫 JSON 中的屬性值只允許 字符串、數(shù)字、數(shù)組、true、false、null或其它JSON對(duì)象 JSON 中屬性值不允許是函數(shù) JSON.parse() 不會(huì)處理計(jì)算屬性名,會(huì)拋語(yǔ)法錯(cuò)誤Object.length
返回 Object() 構(gòu)造函數(shù)形參數(shù)量,值為 1
Object.prototype Object.prototype.hasOwnProperty()檢查對(duì)象自身中是否有某屬性(忽略原型鏈中的屬性)
Object.prototype.isPrototypeOf()檢查當(dāng)前原型是否在指定對(duì)象的原型中 (作用等同于 instanceof)
Object.prototype.propertyIsEnumerable()判斷屬性是否可枚舉
Object.prototype.toLocaleString()返回對(duì)象的字符串表示(用于派生對(duì)象重載)
Array.prototype.toLocaleString([locales[,options]]) Number.prototype.toLocaleString([locales[,options]]) Date.prototype.toLocaleString([locales[,options]])
新的 locales 和 options 參數(shù)讓應(yīng)用程序可以指定要進(jìn)行格式轉(zhuǎn)換的語(yǔ)言,并且定制函數(shù)的行為
在舊的實(shí)現(xiàn)中,會(huì)忽略 locales 和 options 參數(shù),使用的語(yǔ)言環(huán)境和返回的字符串的形式完全取決于實(shí)現(xiàn)方式。
locales 和 options 不同的瀏覽器及版本有兼容性問題,所以這個(gè)api并沒有得到廣泛的應(yīng)用
var prices = ["¥7", 500, 8123, 12]; prices.toLocaleString("ja-JP", { style: "currency", currency: "JPY" }); // "¥7,¥500,¥8,123,¥12" const num = 2333333; num.toLocaleString("zh", { style: "decimal" }); //2,333,333 num.toLocaleString("zh", { style: "percent" }); //233,333,300% const num = 2333333; num.toLocaleString("zh", { style: "currency", currency: "CNY" }); //¥2,333,333.00 num.toLocaleString("zh", { style: "currency", currency: "cny", currencyDisplay: "code" }); //CNY2,333,333.00 let num = 2333.3; num.toLocaleString("zh", { minimumIntegerDigits: 5 }); //02,333.3 //如果不想有分隔符,可以指定useGrouping為false num.toLocaleString("zh", { minimumIntegerDigits: 5, useGrouping: false }); //02333.3 num.toLocaleString("zh", { minimumFractionDigits: 2, useGrouping: false }); //2333.30 num = 666.666 num.toLocaleString("zh", { maximumFractionDigits: 2, useGrouping: false }); //666.67Object.prototype.toString()
返回對(duì)象的字符串表示
使用 toString 來(lái)檢查對(duì)象類型
function isNull(){
Object.prototype.toString.call(obj) === "[object Null]"
}
返回一個(gè)表示該對(duì)象的字符串
Object.assign()將可枚舉的屬性從一個(gè)或多個(gè)源拷貝到目標(biāo)對(duì)象
但是只能深拷貝非嵌套的對(duì)象,嵌套屬性為淺拷貝
簡(jiǎn)單的深拷貝
JSON.parse(JSON.stringify(Obj)), 缺點(diǎn)是會(huì)破壞對(duì)象的原型鏈,并且會(huì)丟失對(duì)象的方法
Object.create(proto, [propsObj])使用指定的原型創(chuàng)建對(duì)象
// ES5實(shí)現(xiàn) (不支持 propsObj) function extend(proto){ function F(){}; F.prototype = proto; return new F(); } // 創(chuàng)建一個(gè)原型為null的空對(duì)象 var o = Object.create(null) var o = {} // 相當(dāng)于 var o = Object.create(Object.prototype) // 為所創(chuàng)建的對(duì)象添加屬性 (如果缺省配置,默認(rèn)為false) var o = Object.create(Object.prototype, { foo: { writeable: true, configurable: true, enumerable: true, value: "hello" } }) function MyClass (){} var o = new MyClass() // 相當(dāng)于 var o = Object.create(Myclass.prototype)
Object.assign 只會(huì)拷貝源對(duì)象自身且可枚舉的屬性,會(huì)調(diào)用 源對(duì)象的 get 和 目標(biāo)對(duì)象的 set 方法,
如果源對(duì)象的屬性 get 方法是自定義的,合并后,將會(huì)丟失
合并時(shí),不會(huì)跳過(guò)那些值為 null 或 undefined 的源對(duì)象
Ojbect.assign 的ES5中的 polyfill
Object.defineProperty(Object, "assign", { value: function assign(target, varArgs) { "use strict"; if (target == null) { throw new TypeError("Connot convert undefined or null to object"); } var to = Object(target); for (var index = 1; index < arguments.length; index++) { var nextSource = arguments[index] for (var nextKey in nextSource) { if(Object.prototype.hasOwnProperty.call(nextSource, nextKey)) { to[nextKey] = nextSource[nextKey]; } } } return to; }, writeable: true, configurable: true, })Object.defineProperty(obj, prop, descriptor)
定義或修改屬性對(duì)象
obj: 要定義屬性的對(duì)象 prop: 屬性名稱 descriptor: 屬性描述
屬性描述 descriptor 分為兩種:數(shù)據(jù)描述符 和 存取描述符
數(shù)據(jù)描述符:一個(gè)有值的屬性,可配置 是否可枚舉、是否可配置、是否可賦值 及 value值
存取描述符:有 getter、setter 函數(shù)的屬性,也可配置 是否可配置及是否可枚舉 屬性描述只能是 數(shù)據(jù)描述 或 存取描述 中的一種
數(shù)據(jù)描述符 描述的屬性只可能有 configurable、enumerable、writeable、value
存取描述符 描述的屬性只可能有 get、set、configurable、enumerable 四個(gè)配置 如果一個(gè)描述符不具有value,writable,get 和 set 任意一個(gè)關(guān)鍵字,那么它將被認(rèn)為是一個(gè)數(shù)據(jù)描述符 // 數(shù)據(jù)描述符 描述的屬性 Object.defineProperty({}, "a", { // 是否可枚舉 決定了是否可被 for...in 和 Object.keys() 獲取屬性名 enumerabel: true, // 屬性描述是否可改變,該屬性是否可刪除,當(dāng)前配置為false時(shí),不能在數(shù)據(jù)和訪問器屬性類型之間切換,不可刪除,除 writable 之外的描述不可修改 configurable: true, // 是否可賦值 writeable: true, // 屬性值,默認(rèn)為 undefined value: 1 }) // 存取描述符 描述的屬性 var bValue; Object.defineProperty({}, "b", { get: function(){ return value; }, set: function(newValue){ bValue = newValue }, enumerable: true, configurable: true, }) function Archiver () { var temp = null; var history = [] Object.defineProperty(this, "temp", { get: function () { console.log("get") return temp; }, set: function (newV) { temp = newV history.push({val: temp}) } }) this.getHistory = function(){ return history; }; } var arc = new Archiver() arc.temp arc.temp = 11 arc.temp = 13 arc.getHistory() // [{ val: 11 }, { val: 13 }]Object.defineProperties(obj, props)
定義或修改多個(gè)屬性對(duì)象 與 Object.defineProperty 一樣
var obj = {}; Object.defineProperties(obj, { "property1": { value: true, writable: true }, "property2": { value: "Hello", writable: false } });Object.entries()
返回可枚舉屬性的鍵值對(duì)數(shù)組
// 獲取 const obj = { foo: "bar", baz: 42 }; console.log(Object.entries(obj)); // [ ["foo", "bar"], ["baz", 42] ] // 遍歷 for...of const obj = { a: 5, b: 7, c: 9}; for(const [key, value] of Object.entries(obj)) { console.log(`${key} ${value}`); } // 遍歷 forEach Object.entries(obj).forEach(([key, value]) => { console.log(`${key} ${value}`); // "a 5", "b 7", "c 9" }); // Object 轉(zhuǎn) Map new Map(Object.entries(obj))Object.freeze()
凍結(jié)一個(gè)對(duì)象,被凍結(jié)的對(duì)象,不可添加、刪除、修改其屬性,也不可修改屬性的描述配置,返回被凍結(jié)的對(duì)象
只能凍結(jié)對(duì)象中的第一層的常量對(duì)象,不可凍結(jié)復(fù)雜對(duì)象
obj1 = { internal: {} }; Object.freeze(obj1); obj1.internal.a = "aValue"; obj1.internal.a // "aValue" 自定義一個(gè)深凍結(jié)函數(shù) function deepFreeze(obj){ const propNames = Object.getOwnPropertyNames(obj); propNames.forEach(name => { const prop = obj[name]; if(typeof prop === "object" && prop !== null) { deepFreeze(prop) } }) return Object.freeze(obj) }Object.isFrozen()
返回指定對(duì)象是否是凍結(jié)對(duì)象
Object.seal()封閉一個(gè)對(duì)象,對(duì)象屬性不可刪除,不可增加新屬性,不可修改屬性描述配置,但 可以修改屬性值
const object1 = { property1: 42 }; Object.seal(object1); object1.property1 = 33; console.log(object1.property1); // expected output: 33 delete object1.property1; // cannot delete when sealed console.log(object1.property1); // expected output: 33 Object.isSealed()
返回指定對(duì)象是否是封閉對(duì)象
獲取對(duì)象自身可枚舉的屬性
Object.keys()與 for...in 不同的是:for...in 還會(huì)遍歷對(duì)象原型鏈中的屬性
使用 for...in 獲取對(duì)象自身可枚舉的屬性
for(key in obj) { obj.hasOwnProperty(key){ console.log(key) } }Object.values()
返回可枚舉的屬性數(shù)組
const obj = { foo: "bar", baz: 42 }; console.log(Object.entries(obj)); // [ ["foo", "bar"], ["baz", 42] ]Object.getOwnPropertyNames()
獲取對(duì)象自身的屬性 (枚舉&不能枚舉)
獲取對(duì)象自身不可枚舉的屬性?
var allProps = Object.getOwnPropertyNames(obj) var enumProps = Object.keys(obj) var noenumProps = allProps.filter(v => enumProps.indexOf(v) === -1)Object.getOwnPropertySymbols()
返回對(duì)象自身所有 Symbol 屬性數(shù)組
對(duì)象自身屬性 包含了兩種類型,一種是 字符串屬性,一種是 Symbol 數(shù)據(jù)屬性,
字符串屬性名可由 Object.getOwnPropertyNames() 來(lái)獲取
Symbol 屬性名可由 Ojbect.getOwnPropertySymbols() 來(lái)獲取
默認(rèn)對(duì)象是不含有 Symbol 屬性的,除非手動(dòng)添加了 Symbol 屬性
返回 對(duì)象自身屬性的 描述配置信息
Object.getOwnPropertyDescriptors()返回 對(duì)象自身所有屬性的 描述配置信息
屬性描述分為兩種:存取描述 與 數(shù)據(jù)描述
var o = { get foo() { return 17; } }; var d = Object.getOwnPropertyDescriptor(o, "foo"); // d { // configurable: true, // enumerable: true, // get: /*the getter function*/, // set: undefined // } var o = { bar: 42 }; var d = Object.getOwnPropertyDescriptor(o, "bar"); // d { // configurable: true, // enumerable: true, // value: 42, // writable: true // }
Object.assign() 無(wú)法拷貝源對(duì)象屬性的特性,且屬性描述會(huì)被轉(zhuǎn)為數(shù)據(jù)描述,也無(wú)法拷貝源對(duì)象的原型
使用 Object.create() 可以完整的淺拷貝一個(gè)對(duì)象
Object.create(Object.getPrototypeOf(obj), Object.getOwnPropertyDescriptors(obj))Object.getPrototypeOf()
返回指定對(duì)象的原型
var proto = {}; var obj = Object.create(proto); Object.getPrototypeOf(obj) === proto; // trueObject.setPrototypeOf()
設(shè)置指定對(duì)象的原型
這個(gè)方法是ES6中的方法,用于替換ES5中 Object.prototype.__proto__ = newProto 的方式修改原型
修改原型對(duì)于瀏覽器是一個(gè)耗性能的方法,應(yīng)避免去修改原型,使用 Object.create() 去創(chuàng)建新的對(duì)象
Object.is()同值相等比較 比較兩個(gè)值是否相等
與抽象相等 == 區(qū)別:
同值相等不會(huì)去隱式轉(zhuǎn)換數(shù)據(jù)類型
與嚴(yán)格相等 === 區(qū)別:
同值相告對(duì)于 -0與+0 返回 false, 而嚴(yán)格相等返回 true
對(duì)于 NaN 與 NaN,同值相等返回 true, 嚴(yán)格相等返回 false
Object.is(0, -0); // false Object.is(-0, -0); // true Object.is(NaN, 0/0); // true 0 === -0 //true +0 === -0 //true NaN === NaN //falseObject.isExtensible()
判斷指定對(duì)象是否可以擴(kuò)展 (是否可以添加屬性及原型)返回 Boolean
var empty = {}; Object.isExtensible(empty); // === trueObject.preventExtensions()
禁止對(duì)象擴(kuò)展 已有的屬性可以修改、刪除,但不能再添加新的屬性
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/96649.html
摘要:它不區(qū)分該屬性是對(duì)象自身的屬性,還是繼承的屬性。那么我們要遍歷對(duì)象所有屬性,包括繼承以及不可遍歷的屬性,用加原型遍歷實(shí)現(xiàn)類似的用遞歸 Object靜態(tài)方法 Object自身方法,必須由Object調(diào)用,實(shí)例對(duì)象并不能調(diào)用 Object.getPrototypeOf() 作用是獲取目標(biāo)對(duì)象的原型 function F() {}; var obj = new F(); console.lo...
摘要:原型鏈與繼承當(dāng)談到繼承時(shí),只有一種結(jié)構(gòu)對(duì)象。如果對(duì)該圖不怎么理解,不要著急,繼續(xù)往下看基于原型鏈的繼承對(duì)象是動(dòng)態(tài)的屬性包指其自己的屬性。當(dāng)使用操作符來(lái)作用這個(gè)函數(shù)時(shí),它就可以被稱為構(gòu)造方法構(gòu)造函數(shù)。 原型鏈與繼承 當(dāng)談到繼承時(shí),JavaScript 只有一種結(jié)構(gòu):對(duì)象。每個(gè)實(shí)例對(duì)象(object )都有一個(gè)私有屬性(稱之為proto)指向它的原型對(duì)象(prototype)。該原型對(duì)象也...
摘要:今天,就我們就來(lái)一步步解析響應(yīng)式的原理,并且來(lái)實(shí)現(xiàn)一個(gè)簡(jiǎn)單的。當(dāng)然,這個(gè)也只是一個(gè)簡(jiǎn)單的,來(lái)說(shuō)明響應(yīng)式的原理,真實(shí)的源碼會(huì)更加復(fù)雜,因?yàn)榧恿撕芏嗥渌壿?。接下?lái)我可能會(huì)將其與聯(lián)系起來(lái),實(shí)現(xiàn)和語(yǔ)法。 從很久之前就已經(jīng)接觸過(guò)了angularjs了,當(dāng)時(shí)就已經(jīng)了解到,angularjs是通過(guò)臟檢查來(lái)實(shí)現(xiàn)數(shù)據(jù)監(jiān)測(cè)以及頁(yè)面更新渲染。之后,再接觸了vue.js,當(dāng)時(shí)也一度很好奇vue.js是如何監(jiān)...
摘要:對(duì)象與屬性讓我們保持耐心,再梳理一下對(duì)象與屬性的關(guān)系對(duì)象是屬性的集合,當(dāng)對(duì)象的屬性是函數(shù)時(shí),我們將其稱之為方法。 這篇博文的主要目的是為了填坑,很久之前我發(fā)表了一篇名為關(guān)于JavaScript對(duì)象中的一切(一) — 對(duì)象屬性的文章,想要談一談JavaScript對(duì)象,可那時(shí)只是貼了一張關(guān)于這個(gè)主題的思維導(dǎo)圖,今天我會(huì)針對(duì)這一主題進(jìn)行展開,將JavaScript對(duì)象一些平常不太常用的知識(shí)...
閱讀 1715·2021-11-18 10:02
閱讀 2230·2021-11-15 11:38
閱讀 2680·2019-08-30 15:52
閱讀 2204·2019-08-29 14:04
閱讀 3242·2019-08-29 12:29
閱讀 2095·2019-08-26 11:44
閱讀 1005·2019-08-26 10:28
閱讀 843·2019-08-23 18:37