国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

JavaScript對象詳解

fancyLuo / 1587人閱讀

摘要:屬性描述符升級打怪必備技能對象有自己的屬性和方法,對于我們對象的屬性來講,屬性還有自己的屬性,又稱為屬性描述符。這個方法接受三個參數(shù),第一個是指定的對象,第二個是指定的對象參數(shù),第三個當(dāng)然是要修改的屬性描述符了。

對象的聲明有倆種:

字面量

通過new一個構(gòu)造函數(shù)Object

兩者唯一的區(qū)別就是,字面量形式,可以一次賦值多個,通過new Object就得一個一個賦值

數(shù)據(jù)類型

JS種7種數(shù)據(jù)類型

number

string

undefined

null

boolean

object

symbol(es6新增,也不算新了,es6都多久了...)

簡單數(shù)據(jù)類型

number

string

undefined

null

boolean

復(fù)雜基本類型(內(nèi)置對象,object子類型)

Number

String

Boolean

Object

Function

Array

RegExp

Date

Error

補(bǔ)充:null為什么是基本類型但是依然會出現(xiàn),typeof null 會返回 object?這是一個語言的bug,原理如下:原理是這樣的,不同的對象在底層都表示為二進(jìn)制,在 JavaScript 中二進(jìn)制前三位都為 0 的話會被判
斷為 object 類型,null 的二進(jìn)制表示是全 0,自然前三位也是 0,所以執(zhí)行 typeof 時會返回“object”。

深入對比基本類型和復(fù)雜類型的區(qū)別,用string和String對比

var str = "hello world";
var strObj = new String("hello String");

str.length                          // 11
strObj.length                    // 12

// typeof判斷屬于那種簡單數(shù)據(jù)類型
typeof str;                         // "string"
typeof strObj;                     //"object"

// instanceof判斷對象實例的鼻祖是哪個復(fù)雜類型
str instanceof String         //  false
strObj instanceof String   // true

這段代碼可以分析出,str通過字面量形式聲明,其數(shù)據(jù)類型為基本數(shù)據(jù)類型,并不是對象,strObj 為復(fù)雜數(shù)據(jù)類型String的實例。我們知道str, strObj的數(shù)據(jù)類型之后,就要拋出一個問題,為什么str并不是對象,它怎么就能調(diào)用length呢?這不是一個簡單數(shù)據(jù)類型該有的呀。js向你丟出一個結(jié)論,那就是簡單數(shù)據(jù)類型存在一個隱式轉(zhuǎn)換,它會從簡單數(shù)據(jù)類型轉(zhuǎn)換為復(fù)雜數(shù)據(jù)類型。

對象 1. 對象的屬性

首先以對象字面量整一個對象

let obj = {
    name: "hello",
    age: 12
}

訪問對象的屬性可以通過 圓點運算符 類似于 obj.name, 還可以通過屬性運算符 obj["name"]訪問。

2. 淺拷貝,深拷貝

ES6 定義了Object.assign()方法實現(xiàn)淺復(fù)制,該方法第一個參數(shù)是目標(biāo)對象,之后還可以跟一個或多個原對象,他會遍歷一個或多個原對象所有可枚舉的自有鍵并把他們復(fù)制(使用 = 操作符賦值,所以這種僵硬的賦值操作,不會將原對象的屬性的特性復(fù)制過來)到目標(biāo)對象,最后返回目標(biāo)對象。

3. 屬性描述符【升級打怪必備技能】

對象有自己的屬性和方法,對于我們js對象的屬性來講,屬性還有自己的“屬性”,又稱為屬性描述符。不要小看這個屬性描述符,可不得了,通過屬性描述符,我們不僅僅可以配置屬性是讀寫權(quán)限,甚至通過setter,getter實現(xiàn)我們的數(shù)據(jù)雙向綁定。該介紹一下這位調(diào)用屬性描述符的內(nèi)置方法了:Object.defineProperty()。這個方法接受三個參數(shù),第一個是指定的對象,第二個是指定的對象參數(shù),第三個當(dāng)然是要修改的屬性描述符了。當(dāng)對象中不存在指定的屬性,Object.defineProperty()就創(chuàng)建這個屬性,當(dāng)描述符中省略某些字段時,這些字段將使用它們的默認(rèn)值,擁有布爾值的字段的默認(rèn)值都是false

所以這也就是說,通過Object.defineProperty()創(chuàng)建的屬性,描述符是不可配置的,因為configurable:false
// 直接對一個對象使用原點運算符賦值,屬性描述符都是true
var o = {};

o.a = 1;
// 等同于 :
Object.defineProperty(o, "a", {
  value : 1,
  writable : true,
  configurable : true,
  enumerable : true
});


// 另一方面,使用Object.defineProperty()卻將屬性修飾符關(guān)閉了
Object.defineProperty(o, "a", { value : 1 });
// 等同于 :
Object.defineProperty(o, "a", {
  value : 1,
  writable : false,
  configurable : false,
  enumerable : false
});
var obj = {
    name: "hello",
    age: 12
}

Object.defineProperty(obj, "name", {
    value: 2,
    writable: true,
    configurable: true,
    enumerable: true
})

obj.name;       //2 not hello

接下來,我們解釋一下屬性描述符的四大天王:value, writable, configurable, enumerable

configurable

為啥先要介紹configurable呢,不得不說說他的重要性,這個描述符的值是true/false,它表示屬性描述符是否可配置,當(dāng)值為false時,剩下的描述符都是不可配置的,修改也不會生效,不包括value。簡單的說,configurable控制的其他描述符的命運!后面我們討論的時候,默認(rèn)configurable為true,不然,討論也沒有意義,根本不會改變嘛

var a = {
    name: "tom",
    age: 22
}

Object.defineProperty(a, "age", {
    enumerable: false,
    writable:false,
    configurable: false,
})
a.age = 12;   // a.age 為12.即使writable 是false,因為configurable是false,所以writable其實還是默認(rèn)的true

我知道你肯定是不信的,直接上圖。Object.getOwnPropertyDescriptor() 與Object.defineProperty()互為一對兒,一個定義,一個查看定義

而且,將configurable修改為false,這是一個單向操作,你想再次修改它的值為true以實現(xiàn)重新配置屬性描述符是不可能的,一旦設(shè)置false,永遠(yuǎn)都是false了。聽說你還不信,那我再上圖

var myObject = {
    a:2
};
myObject.a = 3;
myObject.a; // 3
Object.defineProperty( myObject, "a", {
    value: 4,
    writable: true,
    configurable: false, // 不可配置!
enumerable: true
} );

myObject.a; // 4
myObject.a = 5;
myObject.a; // 5

Object.defineProperty( myObject, "a", {
    value: 6,
    writable: true,
    configurable: true,
    enumerable: true
} ); // TypeError

writable

我們介紹一下控制讀寫的小伙伴-writable,這個屬性描述符控制我們是否可以對屬性進(jìn)行賦值,值為false時,賦值是不管用的。嚴(yán)格模式下,還會拋出錯誤。至于writable怎么處理屬性是否能被賦值,留一個疑問,稍后馬上揭曉。

// configurable為true
var myObject = {};

Object.defineProperty( myObject, "a", {
    value: 2,
    writable: false, // 不可寫!
    configurable: true,
    enumerable: true
} );

myObject.a = 3;
myObject.a; // 2

Enumerable

這個屬性修飾符可能沒有那么直觀,但是從字面來看,我們應(yīng)該是能了解到的,這是控制屬性是否能出現(xiàn)在對象可枚舉屬性中。如果將enumerable設(shè)置為false,屬性就不會出現(xiàn)在可枚舉屬性中。enumerable定義了對象的屬性是否可以在 for...in 循環(huán)和 Object.keys() 中被枚舉。

var obj = {
    name: "tom",
    age: 12
}

for(prop in obj) {
    console.log(prop);     // name, age
}

Object.defineProperty(obj, "name", {
    enumerable: false,
})

for(prop in obj) {
    console.log(prop);                //age
}

補(bǔ)充一些可枚舉相關(guān)的知識,什么叫可枚舉屬性,就是指那些屬性描述符設(shè)置為enumerable為true的屬性。有很多方法是基于可枚舉性的。比如,Object.keys(), in, for in 。對于上面那個例子,就是使用了for in遍歷obj對象可枚舉屬性。

tips: 利用屬性修飾符拓展的功能

ES6 實現(xiàn)的常量const
本身JS是沒有常量這個概念的,但是我們可以使用writable:false 和 configurable:false,就可以創(chuàng)建一個一次賦值,不能修改的常量

禁止拓展
如果想禁止一個對象添加新屬性并且保留已有屬性,可以使用Object.preventExtensions(),這樣顯式賦值就會靜默失敗,嚴(yán)格模式下,將會拋出TypeError異常

密封,禁止拓展加強(qiáng)版,已有的屬性以及屬性修飾符都不能改
Object.seal(..) 會創(chuàng)建一個“密封”的對象,這個方法實際上會在一個現(xiàn)有對象上調(diào)用
Object.preventExtensions(..) 并把所有現(xiàn)有屬性標(biāo)記為 configurable:false。
所以,密封之后不僅不能添加新屬性,也不能重新配置或者刪除任何現(xiàn)有屬性(雖然可以
修改屬性的值)。

凍結(jié),更狠,Object.seal() 加強(qiáng)版,直接修改屬性修飾符writable:false,值都不能動了。
Object.freeze(..) 會創(chuàng)建一個凍結(jié)對象,這個方法實際上會在一個現(xiàn)有對象上調(diào)用
Object.seal(..) 并把所有“數(shù)據(jù)訪問”屬性標(biāo)記為 writable:false,這樣就無法修改它們
的值。

4. Getter/Setter

ES5可以使用getter和setter部分改寫默認(rèn)操作,但是只能應(yīng)用在單個屬性上,無法應(yīng)用在整個對象上,getter,setter都是隱藏函數(shù),前者在獲取屬性值時自動調(diào)用,后者是在設(shè)置屬性值時自動調(diào)用。其實現(xiàn)在,我們可以總結(jié)一下前文所述。屬性描述符其實分為兩種

數(shù)據(jù)修飾符

訪問修飾符

而我們前文一直在講述數(shù)據(jù)修飾符,那么什么是訪問修飾符呢?
當(dāng)我們給一個屬性定義getter和setter或者兩者都有時,這個屬性會被定義為”訪問描述符“,對于訪問描述符而言,JavaScript會忽略它們的value和writable特性,取而代之的是關(guān)心set/get(還有configurable和enumerable)特性

實例演示:

function Archiver() {
  var temperature = null;
  var archive = [];

  Object.defineProperty(this, "temperature", {
    get: function() {
      console.log("get!");
      return temperature;
    },
    set: function(value) {
      temperature = value;
      archive.push({ val: temperature });
    }
  });

  this.getArchive = function() { return archive; };
}

var arc = new Archiver();
arc.temperature; // "get!"
arc.temperature = 11;
arc.temperature = 13;
arc.getArchive(); // [{ val: 11 }, { val: 13 }]

一言以蔽之,setter/getter無非就是我們在賦值或者讀取變量時,預(yù)先悄悄調(diào)用的一個隱藏方法。
還有一種通過對象文字語法創(chuàng)建的get,set(我也是從《你不知道的js》看到這種用法的,MDN這相關(guān)的文檔中我并沒有看到,學(xué)到了),這個不是通過Object.defineProperty()創(chuàng)建的,二者都會在對象中創(chuàng)建一個不包含值的屬性,對于這個屬性的訪問會自動調(diào)用一個隱藏函數(shù),它的返回值會被當(dāng)作屬性訪問的返回值。

其實可以更細(xì)致的觀察到,通過對象文字語法創(chuàng)建的變量,他的修飾符按照規(guī)則肯定是沒有value的,但是其他配置信息是true,這一點很關(guān)鍵

大體上對象的內(nèi)容就是這么多,后續(xù)在做一個補(bǔ)充,MDN實在是前端寶典,看到這里更推薦讀者閱讀MDN相關(guān)文檔:https://developer.mozilla.org...

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

轉(zhuǎn)載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/108314.html

相關(guān)文章

  • 【連載】前端個人文章整理-從基礎(chǔ)到入門

    摘要:個人前端文章整理從最開始萌生寫文章的想法,到著手開始寫,再到現(xiàn)在已經(jīng)一年的時間了,由于工作比較忙,更新緩慢,后面還是會繼更新,現(xiàn)將已經(jīng)寫好的文章整理一個目錄,方便更多的小伙伴去學(xué)習(xí)。 showImg(https://segmentfault.com/img/remote/1460000017490740?w=1920&h=1080); 個人前端文章整理 從最開始萌生寫文章的想法,到著手...

    madthumb 評論0 收藏0
  • javaScript原型及原型鏈詳解(二)

    摘要:當(dāng)然這還沒完,因為我們還有重要的一步?jīng)]完成,沒錯就是上面的第行代碼,如果沒有這行代碼實例中的指針是指向構(gòu)造函數(shù)的,這樣顯然是不對的,因為正常情況下應(yīng)該指向它的構(gòu)造函數(shù),因此我們需要手動更改使重新指向?qū)ο蟆? 第一節(jié)內(nèi)容:javaScript原型及原型鏈詳解(二) 第一節(jié)中我們介紹了javascript中的原型和原型鏈,這一節(jié)我們來講利用原型和原型鏈我們可以做些什么。 普通對象的繼承 ...

    widuu 評論0 收藏0
  • javascript對象原型成員詳解

    摘要:和的作用一樣,區(qū)別在于寫法語法對象對象作用判斷對象是否在對象的原型鏈上語法對象構(gòu)造函數(shù)作用判斷構(gòu)造函數(shù)的屬性是否在對象的原型鏈上,如果在,就返回屬性是否可枚舉用于檢查給定的屬性是否能夠使用語句。 ## javascript對象原型成員詳解 ## ECMAScript 中的對象就是一組數(shù)據(jù)和功能的集合,對象可以通過 new 操作符后跟要創(chuàng)建的對象名稱來...

    zhkai 評論0 收藏0
  • JavaScript深入淺出

    摘要:理解的函數(shù)基礎(chǔ)要搞好深入淺出原型使用原型模型,雖然這經(jīng)常被當(dāng)作缺點提及,但是只要善于運用,其實基于原型的繼承模型比傳統(tǒng)的類繼承還要強(qiáng)大。中文指南基本操作指南二繼續(xù)熟悉的幾對方法,包括,,。商業(yè)轉(zhuǎn)載請聯(lián)系作者獲得授權(quán),非商業(yè)轉(zhuǎn)載請注明出處。 怎樣使用 this 因為本人屬于偽前端,因此文中只看懂了 8 成左右,希望能夠給大家?guī)韼椭?...(據(jù)說是阿里的前端妹子寫的) this 的值到底...

    blair 評論0 收藏0
  • JavaScript 中 this 的詳解

    摘要:作為構(gòu)造函數(shù)調(diào)用中沒有類,但是可以從構(gòu)造器中創(chuàng)建對象,并提供了運算符來進(jìn)行調(diào)用該構(gòu)造器。構(gòu)造器的外表跟普通函數(shù)一樣,大部分的函數(shù)都可以當(dāng)做構(gòu)造器使用。如果構(gòu)造函數(shù)顯式的返回一個對象,那么則會指向該對象。 this 的指向 this 是 js 中定義的關(guān)鍵字,它自動定義于每一個函數(shù)域內(nèi),但是它的指向卻讓人很迷惑。在實際應(yīng)用中,this 的指向大致可以分為以下四種情況。 1.作為普通函數(shù)調(diào)...

    cyrils 評論0 收藏0

發(fā)表評論

0條評論

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