摘要:所以對(duì)象也可說是一組名字屬性的組合。如果想要訪問,就用專用的方法,包含兩個(gè)參數(shù)對(duì)象名稱,屬性名稱,返回一個(gè)對(duì)象包含具體的特性。
基于《javascript 面向?qū)ο缶氛硐滤悸罚?/p>
ECMA5 對(duì)象的定義是無序?qū)傩缘募希瑢傩钥梢允腔局担瑢?duì)象(包含函數(shù)),屬性都有一個(gè)名字,名字可以是標(biāo)識(shí)符或者是字符串,映射到屬性。所以對(duì)象也可說是一組名字/屬性的組合。
有兩種方式創(chuàng)建對(duì)象:構(gòu)造函數(shù),字面量;
//構(gòu)造函數(shù),先定義,在賦值 var obj1 = new Object(); obj1.name = "obama"; //字面量,直接賦值 var obj2 = { name : "bush" }
讀取屬性也有兩種方式
obj1.name //常用的是使用 . 點(diǎn)號(hào)直接讀取屬性 obj1["name"] //使用中括號(hào)里面是屬性的字符串(有引號(hào))也可以讀取 //如果屬性包含空格或者其他的非合法標(biāo)識(shí)符就只能使用中括號(hào),
屬性有兩種:
1,數(shù)據(jù)屬性 named data property
2,訪問器屬性 named accessor property
兩者的區(qū)別,先看數(shù)據(jù)屬性的例子
var obj = { name : "obama" } obj.name; consle.log(obj.name) //obama //正常情況下,直接訪問obj.name 不會(huì)輸出任何結(jié)果,只是引擎訪問這個(gè)屬性,等待下一步的操 //作,如果有下一步操作,就把這屬性的值返回出來,提供使用如:console.log()。
也就是說,數(shù)據(jù)屬性包含屬性的具體的值,我們可以訪問,訪問器屬性則沒有,只供引擎使用,
那么如何描述這兩個(gè)屬性呢,那就是特性,attribute(描述對(duì)象屬性的屬性),正常情況下,不可訪問,在內(nèi)部用[[ ]]包裹。如果想要訪問,就用專用的方法,
Object.getOwnPropertyDescriptor(object,property)包含兩個(gè)參數(shù)(對(duì)象名稱,屬性名稱),返回一個(gè)對(duì)象包含具體的特性。
var obj = { name : "obama" } var properties = Object.getOwnPropertyDescriptor(obj,"name"); console.dir(properties);
可以看到有四個(gè)屬性,這些就是屬性的數(shù)據(jù)屬性,我們可以訪問的到的,也是可以修改的,使用兩個(gè)特殊的方法
Object.defineProperty(); 定義單個(gè)對(duì)象的屬性
Object.defineProperties(); 定義多個(gè)對(duì)象的屬性
記住使用以上兩個(gè)函數(shù),會(huì)對(duì)把有真假值特性默認(rèn)為false,而正常JS里都是true,如果定義的屬性不存在就會(huì)創(chuàng)建新的屬性!!
var obj1 = { }; Object.defineProperty(obj1,"name",{ configurable : true, //決定其他特性是否可以修改,包含直接刪除delete屬性值即value; enumerable : true, //是否可以枚舉 writable : true, //value 是否可以修改 value : "obama" //對(duì)象屬性真正保存值的地方,上面的都是對(duì)它的描述 } ); var obj1 = { name : "obama" }
上面的兩個(gè)對(duì)象是相等的,我們?cè)谥苯有?duì)象字面量的同時(shí),JS引擎就默認(rèn)生成了上面的屬性,我們也可以修改下
var obj1 = { }; Object.defineProperty(obj1,"name",{ configurable : true, enumerable : false, writable : true, value : "obama" } ); //下面的函數(shù)需要是枚舉特性才能使用 obj1.propertyIsEnumerable("name"); //false console.dir( Object.keys(obj1)); //數(shù)組是空 var properties; for(properties in obj1){ console.log("it has been search") // undefined } //*以下是誤區(qū),in和hasOwnProperty函數(shù)查找的是否有屬性,不論是否可以枚舉* console.log("name" in obj1); //true console.log(obj1.hasOwnProperty("name")) //true
當(dāng)然我們也可以同時(shí)定義多個(gè)屬性
var obj = { }; Object.defineProperties(obj,{ name:{ configurable : true, enumerable : true, writable : true, value : "obama" }, age :{ configurable : true, enumerable : true, writable : true, value : 77 }, behavior: { configurable : true, enumerable : true, writable : true, value : function(){ alert("i am the presdent of Amerca") } } }); obj = { name : "obama", age : 77, behavior : function(){ alert("i am the presdent of Amerca")} }
下面說說訪問器屬性,目前沒有方法,直接查看所有的特性,但是我們可以設(shè)置特性,和數(shù)據(jù)屬性使用一樣的方法,沒有value 和writable這兩個(gè)屬性,但是多[[get]]和[[set]]的方法;
//字面量 var obj = { _name : "obama", //使用下劃線_ 只是約定成俗的寫法,表示私有的(實(shí)際上我們也能訪問) get name(){ //get 后面的name就是我們可以訪問正常的屬性, return this._name; }, set name(value){ this._name = value; } }; //或者使用函數(shù) var obj = { _name : "obama" }; Object.defineProperty(obj,"name",{ get : function (){ return this._name; }, set : function(value){ this._name = value; }, configurable : true, enumerable : true }) console.log(obj.name) //obama
訪問器屬性有趣的地方在于如果我們把get的方法換成其他,比如不返回它的值
get : function(){ return console.log(’i am Kim Jong-un‘); } obj.name //即使只是寫出這個(gè)屬性也會(huì)輸出’i am Kim Jong-un’
我們通過obj.name永遠(yuǎn)得不到想要的值,當(dāng)然這樣設(shè)置沒有任何意思,只是了解JS是如何取得屬性的值,
同時(shí)設(shè)置數(shù)據(jù)屬性和訪問器屬性是會(huì)得到一個(gè)錯(cuò)誤。
屬性首次添加給對(duì)象時(shí),JS就會(huì)在對(duì)象上調(diào)用[[Put]]方法,在對(duì)象內(nèi)部開辟新的節(jié)點(diǎn)保存屬性,這個(gè)新屬性有默認(rèn)的特性,重點(diǎn)是這個(gè)屬性僅會(huì)保存在這對(duì)象上,也就是說是這個(gè)對(duì)象的自有屬性!自有!自有![[Extensible]]方法,確定對(duì)象是否可以擴(kuò)展,有三個(gè)具體的方法:
1,禁止擴(kuò)展
var obj = { name : "obama" }; Object.preventExtensions(obj); obj.age = 77; console.log(obj.age) //undefined; //無法增加屬性,但是可以修改刪除原有屬性 Object.isExtensible(obj) //false 表示不可以擴(kuò)展!
2,對(duì)象封印
var obj = { name : "obama" }; Object.seal(obj); //不僅不可以擴(kuò)展也不可刪除屬性,只能讀寫 delete obj.name //false obj.name = " Kim Jong-un"; console.log(obj.name) // Kim Jong-un //可以修改屬性的writable(修改后只能讀取),只能true ->false,不能false ->true; Object.isSealed(obj); //true; Object.isExtensible(obj) //false;
3,對(duì)象凍結(jié)
var obj = { name : "obama" }; Object.freeze(obj); //凍結(jié)后只可以讀取值,,不可以修改刪除值 Object.isFrozen(obj) //true; Object.isSealed(obj); //true; Object.isExtensible(obj) //false;
對(duì)象還有一個(gè)實(shí)用的方法,Object.getOwnPropertyNames();在對(duì)象本身的屬性不可以枚舉的情況下也能列出,返回一個(gè)數(shù)組,對(duì)比Object.keys() 只能列舉可以枚舉的.
注:上面的例子在嚴(yán)格模式下會(huì)拋出錯(cuò)誤,非嚴(yán)格模式會(huì)失敗
使用構(gòu)造函數(shù)創(chuàng)建對(duì)象存在一個(gè)問題,就是必須使用new 操作符,構(gòu)造函數(shù)也是函數(shù)如果直接調(diào)用的話,會(huì)把內(nèi)部的this作用域指向全局;
function Fn(args){ this.args = args; } var obj1 = Fn("test"); obj1 //undefined args //test var obj2 = new Fn("test"); obj2.args //test; //安全的構(gòu)造函數(shù) function Fn(args){ if( this instanceof Fn){ this.args = args; }else{ return new Fn(args) } } //也可以使用Object.creat()的方法來創(chuàng)建對(duì)象 var obj1 = { }; var obj2 = Object.create(null); //obj2是一個(gè)真正意義上空的對(duì)象,沒有任何的繼承,比obj1更空,obj1繼承Object對(duì)象的屬性和方法。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/85164.html
摘要:所以覺得把這個(gè)執(zhí)行的詳細(xì)過程整理一下,幫助更好的理解。類似的語法報(bào)錯(cuò)的如下圖所示三預(yù)編譯階段代碼塊通過語法分析階段之后,語法都正確的下回進(jìn)入預(yù)編譯階段。另開出新文章詳細(xì)分析,主要介紹執(zhí)行階段中的同步任務(wù)執(zhí)行和異步任務(wù)執(zhí)行機(jī)制事件循環(huán)。 一、概述 js是一種非常靈活的語言,理解js引擎的執(zhí)行過程對(duì)于我們學(xué)習(xí)js是非常有必要的。看了很多這方便文章,大多數(shù)是講的是事件循環(huán)(event loo...
摘要:所以覺得把這個(gè)執(zhí)行的詳細(xì)過程整理一下,幫助更好的理解。類似的語法報(bào)錯(cuò)的如下圖所示三預(yù)編譯階段代碼塊通過語法分析階段之后,語法都正確的下回進(jìn)入預(yù)編譯階段。另開出新文章詳細(xì)分析,主要介紹執(zhí)行階段中的同步任務(wù)執(zhí)行和異步任務(wù)執(zhí)行機(jī)制事件循環(huán)。 一、概述 js是一種非常靈活的語言,理解js引擎的執(zhí)行過程對(duì)于我們學(xué)習(xí)js是非常有必要的。看了很多這方便文章,大多數(shù)是講的是事件循環(huán)(event loo...
摘要:以下知識(shí)點(diǎn)是前輩師兄總結(jié)基礎(chǔ)語義化標(biāo)簽引進(jìn)了一些新的標(biāo)簽,特別注意等,注意的標(biāo)題結(jié)構(gòu)理解瀏覽器解析的過程,理解的樹形結(jié)構(gòu),及相應(yīng)理解標(biāo)簽在各個(gè)瀏覽器上的默認(rèn)樣式代理樣式,理解中的重置樣式表的概念理解等功能性標(biāo)簽理解標(biāo)簽,理解文件提交過程推薦 以下知識(shí)點(diǎn)是前輩師兄總結(jié) 1、HTML/HTML5基礎(chǔ): 1.0、語義化H5標(biāo)簽1.1、H5引進(jìn)了一些新的標(biāo)簽,特別注意article...
摘要:以下知識(shí)點(diǎn)是前輩師兄總結(jié)基礎(chǔ)語義化標(biāo)簽引進(jìn)了一些新的標(biāo)簽,特別注意等,注意的標(biāo)題結(jié)構(gòu)理解瀏覽器解析的過程,理解的樹形結(jié)構(gòu),及相應(yīng)理解標(biāo)簽在各個(gè)瀏覽器上的默認(rèn)樣式代理樣式,理解中的重置樣式表的概念理解等功能性標(biāo)簽理解標(biāo)簽,理解文件提交過程推薦 以下知識(shí)點(diǎn)是前輩師兄總結(jié) 1、HTML/HTML5基礎(chǔ): 1.0、語義化H5標(biāo)簽1.1、H5引進(jìn)了一些新的標(biāo)簽,特別注意article...
摘要:至此作用域鏈創(chuàng)建完畢。好了,通過深入理解作用域鏈,我們能跟好的理解的運(yùn)行機(jī)制和閉包的原理。 前言 理解javascript中的作用域和作用域鏈對(duì)我們理解js這們語言。這次想深入的聊下關(guān)于js執(zhí)行的內(nèi)部機(jī)制,主要討論下,作用域,作用域鏈,閉包的概念。為了更好的理解這些東西,我模擬了當(dāng)一個(gè)函數(shù)執(zhí)行時(shí),js引擎做了哪些事情--那些我們看不見的動(dòng)作。 關(guān)鍵詞: 執(zhí)行環(huán)境 作用域 作用域鏈 變...
20190124問: 如何理解es6中的Proxy? 試題解析:對(duì)proxy的理解,可能會(huì)延伸到vue的雙向綁定 Proxy(代理) 定義 可以理解為為目標(biāo)對(duì)象架設(shè)一層攔截,外界對(duì)該對(duì)象的訪問,都必須通過這層攔截 簡(jiǎn)單示例: const obj = new Proxy({}, { get: (target, key, receiver) => { return JS ...
閱讀 1705·2021-11-24 09:39
閱讀 2488·2021-11-18 10:07
閱讀 3666·2021-08-31 09:40
閱讀 3336·2019-08-30 15:44
閱讀 2634·2019-08-30 12:50
閱讀 3654·2019-08-26 17:04
閱讀 1432·2019-08-26 13:49
閱讀 1268·2019-08-23 18:05