成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

深入了解js對象

cheukyin / 2464人閱讀

摘要:通過創(chuàng)建的對象運(yùn)算符創(chuàng)建并初始化一個(gè)新對象,關(guān)鍵字后跟隨一個(gè)函數(shù)調(diào)用,這里的函數(shù)稱作構(gòu)造函數(shù),構(gòu)造函數(shù)用以初始化一個(gè)新創(chuàng)建的對象。

該文章以收錄: 《JavaScript深入探索之路》 前言

對象是Javascript 的基本類型。對象是一種復(fù)合值,它將很多值(原始值或者其他對象)聚合在一起,可通過名字訪問這些值。對象也可看做是屬性的無序集合。每個(gè)屬性都是一個(gè)名/值對。JavaScript對象還可以從一個(gè)稱為原型的對象繼承屬性。

需要注意的是ES6中對對象也做了一些擴(kuò)展,本文章并沒有特別說明,如果你想了解,可以看看阮老師的ES6書籍。

我們可以把對象的屬性分為三大類

內(nèi)置對象:是有ECMAScript規(guī)范定義的對象或類。例如數(shù)組、函數(shù)、日期和正則表達(dá)式都是內(nèi)置對象。

宿主對象: 是由JavaScript 解析器所嵌入的宿主環(huán)境,客戶端JavaScript 中表示網(wǎng)頁結(jié)構(gòu)的HTMLElement對像均是宿主對象。宿主對象也可以當(dāng)成內(nèi)置對象。

自定義對象:是由運(yùn)行中的JavaScript 代碼創(chuàng)建的對象。

另外還有兩類屬性

自有屬性: 是直接在隊(duì)形中定義的屬性

繼承屬性: 是在對象的原型對象中定義的屬性

創(chuàng)建對象 1.對象字面量(也稱為對象直接量)

創(chuàng)建對象最簡單的方式就是在JavaScripot代碼中使用對象直接量。

let obj = {
    name: "web",
    age: 23,
    sex: "man"
}

對象的屬性名可以是Symbol值,這時(shí)ES6新出的一個(gè)數(shù)據(jù)類型。對象直接量是一個(gè)表達(dá)式,這個(gè)表達(dá)式的每次運(yùn)算都創(chuàng)建并初始化一個(gè)新的對象。每次計(jì)算對象直接量的時(shí)候,也都會計(jì)算它的每個(gè)屬性值。也就是說,如果在一個(gè)重復(fù)調(diào)用的函數(shù)中的循環(huán)體內(nèi)使用了對象直接量,它將創(chuàng)建很多新對象,并且每次創(chuàng)建的對象那個(gè)的屬性值也有可能不同。

2.通過new創(chuàng)建的對象

new運(yùn)算符創(chuàng)建并初始化一個(gè)新對象,關(guān)鍵字new 后跟隨一個(gè)函數(shù)調(diào)用,這里的函數(shù)稱作構(gòu)造函數(shù),構(gòu)造函數(shù)用以初始化一個(gè)新創(chuàng)建的對象。JavaScript語言核心中的原始類型都包含內(nèi)置構(gòu)造函數(shù)。

let obj = new fun();
let ary = new Array();

另外我們需要知道使用new創(chuàng)建的構(gòu)造函數(shù)時(shí)沒有原型的,但是他們最終都會繼承Object.prototype

let ary = new Array();
ary.prototype // undefind
3.Object.create()方法創(chuàng)建對象

Object.create() 該方法創(chuàng)建一個(gè)新對象,它有兩個(gè)參數(shù),第一個(gè)參數(shù)是這個(gè)對象的原型。第二個(gè)參數(shù)用以對對象的屬性進(jìn)行進(jìn)一步描述。Object.create() 是一個(gè)靜態(tài)函數(shù),而不是提供給某個(gè)對象調(diào)用的方法。

let o = {
    name: "jhon",
    age: 23
}
let obj = Object.create(o);

obj.name // jhon
obj.__proto__ === o // true obj的原型鏈指向?qū)ο?o
obj.name === o.name // true

它的第二個(gè)參數(shù)是對屬性的一些數(shù)值,下面我們會講到,對對象屬性特征的一些設(shè)置

對象的屬性操作 1.查詢

對象屬性的查詢我們有可以使用.運(yùn)算符、[]運(yùn)算符或者使用ES6提供的Reflect.get() 方法

let o = {
        name: "jhon",
        age: 23
    }

console.log(o.name) // "jhon"
console.log(o["name"])  // "jhon"
console.log(Reflect.get(o, "name"))  // "jhon"

對于[]來說,方括號內(nèi)必須是一個(gè)計(jì)算結(jié)果為字符串的表達(dá)式(也可以直接是字符串),一般我們用來獲取動態(tài)的屬性。另外我這里不在講解ES6的東西,想了解ES6,可以看看阮一峰老師關(guān)于es6基礎(chǔ)的書籍。

2.刪除

delete 操作符可以刪除屬性,它的操作數(shù)應(yīng)當(dāng)是一個(gè)屬性訪問表達(dá)式,delete只是斷開屬性和宿主對象的聯(lián)系,而不會去操作屬性中的屬性。

let o = {
    name: "jhon",
    age: 23,
    other: {
        address: "HangHai",
    },
}

var obj = o.name;

delete o.name

console.log(o.name) // underfind
console.log(obj) // "jhon"

另外delete運(yùn)算符只能刪除自有屬性,不能刪除繼承屬性,它也不能刪除某些屬性配置為false的屬性。還有全局函數(shù)和var聲明的變量也是不能刪除的。

3.繼承

屬性是可以繼承的,JavaScript對象具有“自有屬性”,也有一些是從原型對象上繼承的屬性。例如函數(shù)的toString()方法我們繼承自O(shè)bject的原型。

4.檢測

檢測屬性的歸屬我們可以使用in運(yùn)算符, hasOwnPreperty()protertyIsEnumerable() 方法。

let o = {
    name: "jhon",
    age: 23,
    other: {
        address: "HangHai",
    },
}

//使用 in 操作符來判讀屬性是否是該對象的自有屬性
// 或繼承的屬性

console.log("name" in o) // true
console.log("toString" in o) // true

//hasOwnProperty()判讀屬性是否是該對象的自有屬性

console.log(o.hasOwnProperty("name")) // true
console.log(o.hasOwnProperty("toString")) // false

propertyIsEnumerable()hasOwnProperty() 的增強(qiáng)版,只有檢測是自有屬性且這個(gè)蘇醒的可枚舉性為true時(shí)它才返回true。

// toString 是不可枚舉的屬性
console.log(o.propertyIsEnumerable("toString")) // false
5.枚舉屬性

我們可以使用for/in 遍歷(枚舉) 屬性,我們可以使用以下方法來遍歷對象的自有屬性

 let o = {
    name: "jhon",
    age: 23,
    other: {
        address: "HangHai",
    },
}

let obj = {}

for (prop in o){
  if(o.hasOwnProperty[prop]) continue;
  obj[prop] = o[prop];
}
6.屬性的set和get

在ECMAScrit5中屬性值是可以用一個(gè)或兩個(gè)方法替代,這兩個(gè)方法就是gettersetter,由getter和setter定義的屬性稱做“存取器屬性”,它不同于“數(shù)據(jù)屬性”。

當(dāng)程序查詢存取器屬性的值時(shí),JavaScript調(diào)用getter方法(無參數(shù))。這個(gè)方法的返回值就是屬性存去表達(dá)式的值,當(dāng)程序設(shè)置一個(gè)存去器屬性的值時(shí),JavaScript調(diào)用setter方法,將賦值表達(dá)式右側(cè)的值當(dāng)做參數(shù)傳入setter。

和數(shù)據(jù)屬性不同的是,存取器屬性不具有可寫性。如果屬性同時(shí)具有g(shù)etter和setter方法,那它是一個(gè)讀/寫屬性,如果它只有g(shù)etter方法,那么他是一個(gè)只讀屬性,如果它只有setter方法,那么他是一個(gè)只寫屬性。

定義存取器屬性的最簡單方法是使用對象直接量的語法:

let o = {
    name: "jhon",
    age: 23,
    get g(){
        console.log("您已經(jīng)拿到年齡")
        return this.age + 10;
    },
    set g(value){
        console.log("您設(shè)置的年齡為: "+ this.age)
    },

} 

console.log(o)
o.g  // 您已經(jīng)拿到年齡
o.g = 10  // 您設(shè)置的年齡為: 23
屬性的幾個(gè)特征

屬性除了名字和值之外,還包含一些表示他們可寫、可枚舉、可配置的特性。

數(shù)據(jù)屬性特性包括:

value

可寫性 writable 默認(rèn) true

可枚舉性 enumerable 默認(rèn) true

可配置性 configurable 默認(rèn) true

存取器屬性特性包括:

讀取 get

寫入 set

可沒舉性 enumerable

可配置性 configurable

為了實(shí)現(xiàn)屬性特性的查詢和設(shè)置操作,ECMAScript5 定義了一個(gè)名為 “屬性描述符”的對象

defineProperty() 設(shè)置某個(gè)屬性的特性

let obj = {
    name: "jhon",
    age: 23,
}
Object.defineProperty(obj,"name",{
    value: "King", // 改寫默認(rèn)值
    writable: false,  // 不可修改屬性值
    enumerable: true, // 可枚舉該屬性
    configurable: true // 可配置該屬性

})    

console.log(obj.name); // "King"
obj.name = "Tom"; // 改寫不會成功
console.log( obj.name); // "King"

我們也可以設(shè)置器存取屬性特性:

let obj = {
    name: "jhon",
    age: 23,
}
// 我們將name設(shè)置成存取屬性器
Object.defineProperty(obj,"name",{
    get: function(){
    return "更改為存取屬性器"
    },
    enumerable: true, // 可枚舉該屬性
    configurable: true // 可配置該屬性

})    

console.log(obj.name);

definePeoperties() 設(shè)置多個(gè)屬性的特性

我們可以使用 definePeoperties()來對多個(gè)屬性的特性進(jìn)行設(shè)置

let obj = {
         name: "jhon",
         age: 23,
}
Object.defineProperties(obj,{
    name:{
    get: function(){
    return "更改為存取屬性器"
    },
    enumerable: true, // 可枚舉該屬性
    configurable: true // 可配置該屬性
    },
    age:{
        writable: false, // 禁止改寫age
    }

})    

console.log(obj.name); //更改為存取屬性器

obj.age = 10;
console.log(obj.age) // 23

getOwnpropertyDescriptor() 獲取某個(gè)對象自有屬性的屬性描述

let obj = {
    name:"jhon"
}

let descriptor = Object.getOwnPropertyDescriptor(obj,"name");

// Object {value: "jhon", writable: true, enumerable: true, configurable: true}
console.log(descriptor)
對象的三個(gè)屬性 1.原型屬性

對象的原型屬性是用來繼承屬性的,原型屬性實(shí)例創(chuàng)建之初就設(shè)置好了,通過對象直接量創(chuàng)建的對象使用對象 Object.prototype 作為他們的原型,通過new創(chuàng)建的對象,使用構(gòu)造函數(shù)prototype屬性作為它們的原型,通過Object.create() 創(chuàng)建的對象使用第一個(gè)參數(shù)(也可以是null)作為他們的原型

在ECMAScript5中,將對象作為參數(shù)傳入Object.getPrototypeOf() 可以查看他的原型。

let obja = {
 name:"jhon"
}

let proto = Object.getPrototypeOf(obja);
console.log(proto) // 返回Objcet的原型

如果想要檢測一個(gè)對象是否是另一個(gè)對象的原型(或處于原型鏈中),可以使用isPrototypeOf() 方法。

     
function fun(name){
    this.name = name
}

fun.prototype = function(){
    console.log("原型")
}

let newFun = new fun("jhon");

// true
console.log(fun.prototype.isPrototypeOf(newFun))

// 另外我們還可以通過 instanceof 來檢測一個(gè)對象是否是另一個(gè)對象的實(shí)例

console.log( newFun instanceof  fun) // true
2.類屬性

對象的雷屬性是一個(gè)字符串,用以表示對象的類型信息,我們可以通過一種間接的方法查詢它。
默認(rèn)的 toString() 方法(繼承自O(shè)bject.prototype) 返回這種格式的字符串:[object class]

我們可以通過 Object.prototype.toString.call() 來檢測對象的class

function fun (){

}

let className = Object.prototype.toString.call(fun);

console.log(className) // [object Function]
3.可擴(kuò)展性

對象的可擴(kuò)展性用以表示是否可以給對象添加新屬相,所有內(nèi)置對象和自定義對象都是顯式可擴(kuò)展的。
這里我們可以通過 Object.esExtensible(),來判斷該對象是否可擴(kuò)展的。

let obj = {
    name: "jhon",
    age: 23,
}

// true  對象obj默認(rèn)是可擴(kuò)展的
console.log(Object.isExtensible(obj))

如果想將對象轉(zhuǎn)換為不可擴(kuò)展的,可以使用 Object.preventExtensions()

let obj = {
        name: "jhon",
        age: 23,
    }

Object.preventExtensions(obj);

obj.address = "BeiJing"

console.log(obj) // obj并沒有多出一個(gè)address屬性
console.log(Object.isExtensible(obj)) // false

注意一旦將對象轉(zhuǎn)換為不可擴(kuò)展的,就無法在將其轉(zhuǎn)換回可擴(kuò)展的了。

如果想將對象轉(zhuǎn)換為不可擴(kuò)展的,并且對象的所有自有屬性都設(shè)置為不可配置(也就是封閉對象),可以使用 Object.seal()
判讀封閉對象可以使用Object.isSealed()

如果想將對象轉(zhuǎn)換為不可擴(kuò)展的,對象的所有自有屬性都設(shè)置為不可配置并且是只讀(也就是凍結(jié)對象),可以使用 Object.frozen(), 如果對象的存取器屬性具有setter方法,存取器屬性將不受影響。 使用Object.isFrozen() 來檢測對象是否凍結(jié)。

Object.preventExtensions()、Object.seal()Object.frozen()都返回傳入的對象。

對象的方法

所用的JavaScript對象都從Objcet.prototype繼承屬性(除了那些不通過原型顯示創(chuàng)建的對象),以下這些方法我不在詳細(xì)介紹,因?yàn)樗麄冞€是比較常用的。

1.toString() 方法

2.toLocaleString() 方法

它僅僅調(diào)用了 toString() 方法并返回對應(yīng)值,DateNumber 類對該方法做了定制。

3.toJson() 方法

Objcet.prototype實(shí)際上沒有定義toJson() 方法,但對于需要執(zhí)行序列化的對象來說,JSON.stringify()方法會調(diào)用該方法。

4.valueOf 方法

當(dāng)JavaScript需要將對象轉(zhuǎn)換為某種原始值而非字符串的時(shí)候才會調(diào)用它。

結(jié)束

參考書籍:《JavaScript權(quán)威指南》

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/89882.html

相關(guān)文章

  • 深入理解JavaScript

    摘要:深入之繼承的多種方式和優(yōu)缺點(diǎn)深入系列第十五篇,講解各種繼承方式和優(yōu)缺點(diǎn)。對于解釋型語言例如來說,通過詞法分析語法分析語法樹,就可以開始解釋執(zhí)行了。 JavaScript深入之繼承的多種方式和優(yōu)缺點(diǎn) JavaScript深入系列第十五篇,講解JavaScript各種繼承方式和優(yōu)缺點(diǎn)。 寫在前面 本文講解JavaScript各種繼承方式和優(yōu)缺點(diǎn)。 但是注意: 這篇文章更像是筆記,哎,再讓我...

    myeveryheart 評論0 收藏0
  • JavaScript 異步

    摘要:從最開始的到封裝后的都在試圖解決異步編程過程中的問題。為了讓編程更美好,我們就需要引入來降低異步編程的復(fù)雜性。寫一個(gè)符合規(guī)范并可配合使用的寫一個(gè)符合規(guī)范并可配合使用的理解的工作原理采用回調(diào)函數(shù)來處理異步編程。 JavaScript怎么使用循環(huán)代替(異步)遞歸 問題描述 在開發(fā)過程中,遇到一個(gè)需求:在系統(tǒng)初始化時(shí)通過http獲取一個(gè)第三方服務(wù)器端的列表,第三方服務(wù)器提供了一個(gè)接口,可通過...

    tuniutech 評論0 收藏0
  • 深入了解 Number 類型

    摘要:下面就讓我們來一起深入了解下,為以后的策馬奔騰做好鋪墊。整數(shù)整數(shù),可以通過十進(jìn)制,八進(jìn)制,十六進(jìn)制的字面值來表示。對前面定義的八進(jìn)制和十六進(jìn)制數(shù)值進(jìn)行運(yùn)算浮點(diǎn)數(shù)浮點(diǎn)數(shù)其實(shí)就是我們通常所說的小數(shù),所以一定有個(gè)小數(shù)點(diǎn)。 Number 類型作為 JS 的基本數(shù)據(jù)類型之一,被應(yīng)用在程序中的各種場景,其重要性就如數(shù)字對于我們?nèi)粘I?。下面就讓我們來一起深入了解下,為以后的策馬奔騰做好鋪墊。 定義...

    scwang90 評論0 收藏0
  • 深入js隱式類型轉(zhuǎn)換

    摘要:結(jié)合實(shí)際中的情況來看,有意或無意中涉及到隱式類型轉(zhuǎn)換的情況還是很多的。此外當(dāng)進(jìn)行某些操作時(shí),變量可以進(jìn)行類型轉(zhuǎn)換,我們主動進(jìn)行的就是顯式類型轉(zhuǎn)換,另一種就是隱式類型轉(zhuǎn)換了。 前言 相信剛開始了解js的時(shí)候,都會遇到 2 ==2,但 1+2 == 1+2為false的情況。這時(shí)候應(yīng)該會是一臉懵逼的狀態(tài),不得不感慨js弱類型的靈活讓人發(fā)指,隱式類型轉(zhuǎn)換就是這么猝不及防。結(jié)合實(shí)際中的情況來看...

    tomato 評論0 收藏0
  • javascript知識點(diǎn)

    摘要:模塊化是隨著前端技術(shù)的發(fā)展,前端代碼爆炸式增長后,工程化所采取的必然措施。目前模塊化的思想分為和。特別指出,事件不等同于異步,回調(diào)也不等同于異步。將會討論安全的類型檢測惰性載入函數(shù)凍結(jié)對象定時(shí)器等話題。 Vue.js 前后端同構(gòu)方案之準(zhǔn)備篇——代碼優(yōu)化 目前 Vue.js 的火爆不亞于當(dāng)初的 React,本人對寫代碼有潔癖,代碼也是藝術(shù)。此篇是準(zhǔn)備篇,工欲善其事,必先利其器。我們先在代...

    Karrdy 評論0 收藏0
  • JS程序

    摘要:設(shè)計(jì)模式是以面向?qū)ο缶幊虨榛A(chǔ)的,的面向?qū)ο缶幊毯蛡鹘y(tǒng)的的面向?qū)ο缶幊逃行┎顒e,這讓我一開始接觸的時(shí)候感到十分痛苦,但是這只能靠自己慢慢積累慢慢思考。想繼續(xù)了解設(shè)計(jì)模式必須要先搞懂面向?qū)ο缶幊?,否則只會讓你自己更痛苦。 JavaScript 中的構(gòu)造函數(shù) 學(xué)習(xí)總結(jié)。知識只有分享才有存在的意義。 是時(shí)候替換你的 for 循環(huán)大法了~ 《小分享》JavaScript中數(shù)組的那些迭代方法~ ...

    melody_lql 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<