摘要:函數(shù)式對象的一個子類型,中的函數(shù)是一等公民內(nèi)置對象中還有一些對象子類型,通常被稱為內(nèi)置對象。內(nèi)容對象的內(nèi)容是由一些存儲在特定命名位置的任意類型的值組成的,我們稱之為屬性。
語法
對象兩種定義形式
聲明(文字)形式
構(gòu)造形式
//聲明(文字)形式 var myObj = { key: value // ... } //構(gòu)造形式 var myObj = new Object(); myObj.key = value;類型
對象是 JavaScript 的基礎(chǔ)。在 JavaScript 中一共有六種主要類型(術(shù)語語言類型)
string
number
boolean
null
undefined
object
注意,簡單基本類型(string,number,boolean,undefined,null)本身并不是對象。
null 有時會被當做對象類型,但這其實只是語言本身的一個 bug,即對 null 執(zhí)行 typeof null 時會返回"object" 。實際上,null 本身是基本類型。
函數(shù)式對象的一個子類型,JavaScript 中的函數(shù)是“一等公民”
內(nèi)置對象JavaScript 中還有一些對象子類型,通常被稱為內(nèi)置對象。有些內(nèi)置對象的名字看起來和簡單基礎(chǔ)類型一樣,不過實際上它們的關(guān)系更復(fù)雜,
String
Number
Boolean
Object
Function
Array
Date
RegExp
Error
這些內(nèi)置函數(shù)可以當做構(gòu)造函數(shù)(由 new 產(chǎn)生的函數(shù)調(diào)用)來使用,從而可以構(gòu)造一個對應(yīng)子類型的新對象。舉例來說:
var strPrimitive = "I am string"; //文字形式定義 typeof(strPrimitive); // "string" strPrimitive instanceof String; // false var strObject = new String("I am string");//構(gòu)造形式定義 typeof(strObject); //"object" strObject instanceof String; //true //檢查 sub-type 對象 Object.prototype.toString.call(strObject);//[object String]
Object.prototype.toString...我們可以認為子類型在內(nèi)部借用了 Object 中的 toString()方法。
由于 javascript 弱類型的編程語言,原始值 "I am string"在必要的時候回自動把字符串字面量轉(zhuǎn)換成一個 String 對象。
思考下面代碼:
var strPrimitive = "I am a string"; console.log(strPrimitive.length); //13 console.log(strPrimitive.charAt(3));//m
使用以上兩種方法,我們都可以直接在字符串字面量上訪問屬性和方法,之所以可以這么做,是因為引擎自動把字面量轉(zhuǎn)換成 String 對象,所以可以訪問屬性和方法。
內(nèi)容null 和 undefined 沒有對應(yīng)的構(gòu)造形式,他們只有文字形式。相反,Date 只有構(gòu)造,沒有文字形式。
對象的內(nèi)容是由一些存儲在特定命名位置的(任意類型的)值組成的,我們稱之為屬性。
var myObject = { a:2, "a_arr":3 } myObject.a; //2 屬性訪問 myObject["a"]; //2 鍵訪問 myObject["a_arr"]; //3
.操作符要求屬性命名滿足標識符的命名規(guī)范,而["..."]語法可以接受任意 UTF-8/Unicode 字符串為屬性名
在對象中,屬性名永遠都是字符串。如果你使用 string(字面量)以外的其他值作為屬性名,那它首先會被轉(zhuǎn)換為一個字符串。即使是數(shù)字也不例外,雖然在數(shù)組下標中使用的的確是數(shù)字,但是在對象屬性名中數(shù)字會被轉(zhuǎn)換成字符串,所以當心不要搞混對象和數(shù)字的用法。
var myObject = {} myObject[true] = "foo"; myObject[3] = "bar"; myObject[myObject] = "baz"; myObject["true"]; //"foo" myObject["3"]; //"bar" myObject["[object Object]"]; //"baz"可計算屬性名
ES6 增加了可計算屬性名,可以再文字形式中使用[]包裹一個表達式來當做屬性名:
var prefix = "foo"; var myObject = { [prefix + "bar"]:"hello", [prefix + "baz"]:"world", }; myObject["foobar"]; //hello myObject["foobaz"]; //world
可計算屬性名最常用的場景可能是 ES6的符號(Symbol)
它是一種新的基礎(chǔ)數(shù)據(jù)類型,包含一個不透明且無法預(yù)測的值
數(shù)組數(shù)組也支持[]訪問形式,數(shù)組期房的是數(shù)值下標,也就是說值存儲的位置(索引)是整數(shù)。
var arr =[1,"a",2]; arr.length; //3 arr[0]; //1 arr[1]; //"a" arr.x = "x"; arr.length; //3 arr.x; //"x" arr["3"] = 3; arr.length; //4 arr[3]; //3
數(shù)組也是對象,所以雖然每個下標都是整數(shù),你仍然可以給數(shù)組添加屬性
注意: 如果你試圖向數(shù)組添加一個屬性,當時屬性名“看起來”想一個數(shù)字,那他會編程一個數(shù)值下標(因此會修改數(shù)組的內(nèi)容而不是添加一個屬性)
復(fù)制對象javascript 初學(xué)者最常見的問題之一就是如何復(fù)制一個對象。實際上我們無法選擇默認一個復(fù)制算法。
舉例來說,思考一下這個對象:
function anotherFunction(){/**/} var anohterObject = { c: true }; var anotherArray = []; var myObject = { a: 2, b: anotherObject,//引用,不是副本 c: anotherArray,//另一個引用 d: anotherFunction }; anotherArray.push( anotherObject, myObject);
對象復(fù)制時,我們應(yīng)該判斷它是淺復(fù)制還是深復(fù)制。
對于淺拷貝來說,復(fù)制出的新對象中 a 的值會復(fù)制舊對象中 b、c、d 引用的對象是一樣的。
對于深拷貝來說,除了復(fù)制 myObject 以外還會復(fù)制 anotherObject 和 anotherArray。這時問題就來了,anotherArray 引用了 anotherObject 和 myObject,所以又需要復(fù)制 myObject,這樣就會由于循環(huán)引用導(dǎo)致死循環(huán)。
有一巧妙的復(fù)制方法:
var newObj = JSON.parse(JSON.stringify( someObj ));
這種方法需要保證對象是 Json 安全的的,所以只適用于部分情況。
相對于深復(fù)制,淺復(fù)制就非常易懂并且問題要少得多,所以 ES6定義了 Object.assign(...)方法來實現(xiàn)淺復(fù)制。
Object.assign() :第一個參數(shù)是目標對象,之后可以跟一個或多個源對象。
它會遍歷一個或多個源對象的所有可枚舉的自由鍵并把他們復(fù)制到目標對象,最后返回目標對象。
var obj = Object.assign({},myObject); obj.a; //2 obj.b === anotherObject;//true obj.c === anotherArray;//true obj.d === anotherFunction;//true屬性描述符
在 ES5之前,JavaScript 語言本身并沒有提供可以直接檢測屬性特性的方法,比如判斷屬性是否可讀。
但是從 ES5開始,所有的屬性都具備了屬性描述符。
思考下面代碼:
var myObject = { a:2 }; Object.getOwnPropertyDescriptor( myObject,"a" ); // { // value:2, // writable:true, // enumerable:true, // configurable:true // }
可以通過 Object.defineProperty(...) 添加或者修改一個已有屬性
Vue 的雙向綁定的基礎(chǔ)就是基于這個函數(shù),重寫 get set 方法,在使用發(fā)布-訂閱模式來完成數(shù)據(jù)的動態(tài)更新
詳情可以看Vue 動態(tài)數(shù)據(jù)綁定(一)和Vue 動態(tài)數(shù)據(jù)綁定三大難點
configurable:false 時:
它將不能再使用Object.defineProperty(...)進行配置
但是可以將 writable的狀態(tài)由 true->false(無法 false->true)
delete 無效
不變性對象常量
結(jié)合 writable:false 和 configurable:false
var myObject ={}; Object.defineProperty( myObject, "NUMBER",{ value:42, writable:false, configurable:false });
禁止擴展
如果你想禁止一個對象添加新屬性并且保存已有屬性,可以使用 Object.preventExtensions(...)
var myObject ={ a:2 } Object.preventExtensions(myObject); myObject.b =3; myObject.b; //undefined
在費嚴格模式下,創(chuàng)建屬性 b 會靜默失敗。在嚴格模式下,將會拋出 TypeError 錯誤。
密封
Object.seal(...)會創(chuàng)建一個"密封"的對象,這個訪問實際上會在一個現(xiàn)有對象上調(diào)用 Object.preventExtensions(...)并把所有現(xiàn)有屬性標記為configurable:false。
密封后,不能添加新屬性,也不能重新配置或刪除任何現(xiàn)有屬性(可以修改屬性的值)
凍結(jié)
Object.freeze(...)會創(chuàng)建一個凍結(jié)對象,這個方法實際上會在一個現(xiàn)有對象調(diào)用 Object.seal(...)并把所有“數(shù)據(jù)訪問”屬性 wirtable:false,這樣就無法修改他們的值了
更多內(nèi)容可以訂閱本人微信公眾號,一起開啟前端小白進階的世界!
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://hztianpu.com/yun/86845.html
摘要:第一點瀏覽器組成部分瀏覽器有兩大核心外殼,注用戶可以操控的部分。第二點主流瀏覽器主流瀏覽器沒有獨立內(nèi)核的瀏覽器不能叫主流瀏覽器瀏覽器是微軟在年發(fā)布的,瞬間代碼能夠執(zhí)行萬行以上。內(nèi)核是年發(fā)布的最新瀏覽器。 第一點:瀏覽器組成部分瀏覽器有兩大核心:shell(外殼,注:用戶可以操控的部分)。內(nèi)核部分(瀏覽器最主要的部分): 1. 渲染引擎(語法規(guī)則與渲染,就是快速繪制頁面)。 2. js引...
摘要:從最開始的到封裝后的都在試圖解決異步編程過程中的問題。為了讓編程更美好,我們就需要引入來降低異步編程的復(fù)雜性。異步編程入門的全稱是前端經(jīng)典面試題從輸入到頁面加載發(fā)生了什么這是一篇開發(fā)的科普類文章,涉及到優(yōu)化等多個方面。 TypeScript 入門教程 從 JavaScript 程序員的角度總結(jié)思考,循序漸進的理解 TypeScript。 網(wǎng)絡(luò)基礎(chǔ)知識之 HTTP 協(xié)議 詳細介紹 HTT...
摘要:前端進階進階構(gòu)建項目一配置最佳實踐狀態(tài)管理之痛點分析與改良開發(fā)中所謂狀態(tài)淺析從時間旅行的烏托邦,看狀態(tài)管理的設(shè)計誤區(qū)使用更好地處理數(shù)據(jù)愛彼迎房源詳情頁中的性能優(yōu)化從零開始,在中構(gòu)建時間旅行式調(diào)試用輕松管理復(fù)雜狀態(tài)如何把業(yè)務(wù)邏輯這個故事講好和 前端進階 webpack webpack進階構(gòu)建項目(一) Webpack 4 配置最佳實踐 react Redux狀態(tài)管理之痛點、分析與...
摘要:的介紹一般是這樣在中,類是隨內(nèi)核一起發(fā)布的核心庫。庫為帶來了一種存儲原始數(shù)據(jù)的方法,可以讓處理二進制數(shù)據(jù),每當需要在中處理操作中移動的數(shù)據(jù)時,就有可能使用庫。這樣傳遞數(shù)據(jù)會更快。 零、開始之前 1、 首先解釋一下node.js是什么? 2、node.js和javascript有什么不同? 1)因為javascript主要是用在browser,而node.js是在server或者你的電腦...
閱讀 1737·2021-09-26 09:55
閱讀 1491·2021-09-23 11:22
閱讀 2830·2021-09-06 15:02
閱讀 2730·2021-09-01 11:43
閱讀 4180·2021-08-27 13:10
閱讀 3776·2021-08-12 13:24
閱讀 2155·2019-08-30 12:56
閱讀 3084·2019-08-30 11:22