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

資訊專欄INFORMATION COLUMN

javascript基礎(chǔ)-Vue數(shù)據(jù)綁定前奏對(duì)象屬性

zebrayoung / 2511人閱讀

摘要:關(guān)于有人說(shuō)我用刪除這個(gè)屬性不就好了之后打印發(fā)現(xiàn)它還是一只哈士奇。如下的解釋如下操作符會(huì)從某個(gè)對(duì)象上移除指定屬性。

javascript-Object-Property

? javascript-對(duì)象的屬性的延伸學(xué)習(xí)

前言

在學(xué)習(xí)vue數(shù)據(jù)綁定的較底層原理時(shí),被setter和getter困惑了很久,一路追根溯源,通過(guò)閱讀《你不知道的javascript》和紅寶書(shū)理解了迷惑我的setter、getter。

首先了解什么是屬性描述符

[](http://xurenjie.cn:3000/img/d...
在ES5之前,javascript語(yǔ)言沒(méi)有提供可以檢驗(yàn)屬性特性的方法,是否只讀?不知道;是否可配置?不知道;是否能用for in枚舉?不知道。

ES5之后就有了如下的屬性描述符:

 var Dogger = {
    breed: "柴犬"
 }

 Object.getOwnPropertyDescriptor( Dogger , "breed" );

輸出:

 {
     value: "柴犬",
     writable: true,
     configurable: true,
     enumerable: true
 }

 

在這,創(chuàng)建了一個(gè)品種為柴犬的dogger。[[Value]]特性將設(shè)置為"柴犬",之后操作對(duì)breed的任何修改將反映到這個(gè)位置。對(duì),沒(méi)錯(cuò),這個(gè)getOwnPropertyDescriptor( Dogger , "breed" )函數(shù)就是我們要的檢驗(yàn)屬性特性的方法。

默認(rèn):在創(chuàng)建普通對(duì)象屬性時(shí),屬性描述符會(huì)使用默認(rèn)值,即可寫(xiě)可配可枚舉。(都為true)

下面分別介紹一下、這幾個(gè)屬性

writeable

決定是否修改屬性的值,是否可以指定新的值給它

    Dogger.breed = "哈士奇"

很好理解,當(dāng)writeable為false的時(shí)候,其實(shí)定義了一個(gè)空的setter(等會(huì)會(huì)提),這個(gè)操作將無(wú)效,在嚴(yán)格模式下會(huì)拋出一個(gè)TypeError的錯(cuò)誤。

configurable

與configurable緊密相連的就是defineProperty( )這個(gè)方法了,當(dāng)configurable: false 將不可使用‘好基友’defineProperty( )來(lái)配置。后面還會(huì)介紹一個(gè)會(huì)受影響的delete

var Dogger = {
    breed: "柴犬"
 }

Object.defineProperty( Dogger, "breed", {
    value: "哈士奇",
    writable: true,
    configurable: false,
    enumerable: true
} )

Dogger.breed // "哈士奇" | 哈哈!我變成了一只哈士奇
Object.defineProperty( Dogger, "breed", {
    value: "柴犬",
    writable: true,
    configurable: true,
    enumerable: true
} ) // TypeError

這只作死的柴犬在通過(guò)defineProperty( )把自己配置成哈士奇之后,順便把configurable修改為false,這樣之后defineProperty( )不管是否嚴(yán)格模式都將報(bào)TypeError的錯(cuò)誤,這是單向操作,無(wú)法撤銷。 一失足成千古恨~
[](http://xurenjie.cn:3000/img/d...

例外

還是可以通過(guò)writable的方式修改breed的嘛~,不過(guò)這里有一個(gè)方法可以讓dogger徹底絕望,使breed無(wú)法修改,也就是這個(gè)例外:這個(gè)時(shí)候defineProperty( )還是可以使用的(如下),只可以修改writable,configurable需要與剛才的false一致。

Object.defineProperty( Dogger, "breed", {
    value: "哈士奇",
    writable: false,
    configurable: false,
    enumerable: true
} )

這樣之后柴犬永遠(yuǎn)變成了只哈士奇。
[](http://xurenjie.cn:3000/img/d...

關(guān)于delete

有人說(shuō)我用delete刪除這個(gè)breed屬性不就好了?

delete Dogger.breed

之后打印dogger發(fā)現(xiàn)它還是一只哈士奇。如下:

MDN的解釋如下

delete 操作符會(huì)從某個(gè)對(duì)象上移除指定屬性。成功刪除的時(shí)候回返回 true,否則返回 false。
Non-configurable properties cannot be removed. This includes properties ofbuilt-in objects like Math, Array, Object and properties that are created as non-configurable with methods like Object.defineProperty( ).
When in strict mode, if delete is used on a direct reference to a variable, a function argument or a function name, it will throw a SyntaxError.
Any variable defined with var is marked as non-configurable. In the following example, salary is non-configurable and cannot be deleted. In non-strict mode, the delete operation will return false.

delete只是用來(lái)直接刪除對(duì)象(可刪除的)屬性,當(dāng)breed屬性是Dogger的最后引用者,對(duì)這個(gè)屬性執(zhí)行delete操作,這個(gè)為引用的對(duì)象就可以被垃圾回收了,不要看成一個(gè)釋放內(nèi)存的工具,而是刪除屬性的操作,僅此。

enumerable

當(dāng)且僅當(dāng)該屬性的 enumerable 為 true 時(shí),該屬性才能夠出現(xiàn)在對(duì)象的枚舉屬性中。默認(rèn)為 false。
屬性特性 enumerable 定義了對(duì)象的屬性是否可以在 for...in 循環(huán)和 Object.keys( ) 中被枚舉。

放上MDN的代碼片段:

var o = {};
Object.defineProperty(o, "a", { value : 1, enumerable:true });
Object.defineProperty(o, "b", { value : 2, enumerable:false });
Object.defineProperty(o, "c", { value : 3 }); // enumerable defaults to false
o.d = 4; // 如果使用直接賦值的方式創(chuàng)建對(duì)象的屬性,則這個(gè)屬性的enumerable為true

for (var i in o) {
console.log(i);
}
// 打印 "a" 和 "d" (in undefined order)

Object.keys(o); // ["a", "d"]

o.propertyIsEnumerable("a"); // true
o.propertyIsEnumerable("b"); // false
o.propertyIsEnumerable("c"); // false

[ [ Get ] ]和[ [ Put ] ] [ [ Get ] ]
Dogger.breed

如上,對(duì)一個(gè)對(duì)象進(jìn)行訪問(wèn)時(shí)有一個(gè)很重要的細(xì)節(jié)。Dogger.breed是一次屬性訪問(wèn),但并不是僅僅在Dogger中查找breed,其實(shí)看起來(lái)更像是在語(yǔ)言規(guī)范中執(zhí)行了Dogger的[ [ Get ] ]操作,看上去像[ [ Get ] ]( )。

在對(duì)象中查找有沒(méi)有這個(gè)屬性。

在該對(duì)象的原型鏈上查找有沒(méi)有這個(gè)屬性。

都沒(méi)找到返回undefined(注意:如果那個(gè)屬性值恰好為undefined時(shí),雖然返回值一樣,但是底層發(fā)生的事是不一樣的

[ [ Put ] ]

[ [ Get ] ]對(duì)應(yīng)[ [ Put ] ]操作,一旦給對(duì)象屬性賦值就觸發(fā)設(shè)置和創(chuàng)建這個(gè)屬性發(fā)生的事情是這樣的:

首先確定是否存在這個(gè)屬性。breed是否存在

存在,是否是setter。是setter就調(diào)用setter,是否是setter來(lái)給breed賦值

writable是否為false,false則無(wú)效。breed的writable是否為false

設(shè)置值為該屬性的值

Getter和Setter

在《 javascript高級(jí)程序設(shè)計(jì) 》中成為訪問(wèn)器屬性,也稱為訪問(wèn)描述符,getter和setter是兩個(gè)隱形的函數(shù),getter為讀取屬性值的函數(shù),setter為設(shè)置屬性值的函數(shù),在訪問(wèn)這個(gè)階段我們關(guān)注的是四個(gè)屬性:

set

get

configurable

enumerable

這時(shí)候我們用Dogger的例子來(lái)了解一下這些特性

var Dogger = {
    get breed() {
 ? ? ? ?return  "柴犬"
 ? ?}
}
Object.defineProperty(
  Dogger
  "breed-type",
  {
    get: function() {
 ? ? ?return this.breed + "品種"
    }
  }
)
Dogger.breed // "柴犬"
Dogger.breed-type // "柴犬品種"

沒(méi)毛病,不管是隱式調(diào)用還是顯式確實(shí)能夠讓我們定義屬性,自動(dòng)調(diào)用隱藏函數(shù),返回值為屬性訪問(wèn)的返回值
[](http://xurenjie.cn:3000/img/d...
如果這時(shí)候,我們想用賦值操作給Dogger改變屬性會(huì)怎么樣?

Dogger.breed = "哈士奇"

Dogger.breed // "柴犬"

由于只定義了breed的getter,所以對(duì)它的值進(jìn)行設(shè)置時(shí)set操作會(huì)忽略賦值操作(也不會(huì)報(bào)錯(cuò))。其實(shí)就算定義了setter,自定義
的getter還是只會(huì)返回getter設(shè)置的值。

因此你去改變屬性的值時(shí),你還需要定義一個(gè)setter,通常來(lái)說(shuō),他們是成雙成對(duì)的。不寫(xiě)嚴(yán)格模式會(huì)報(bào)錯(cuò)。

setter其實(shí)就是我們最常用的賦值操作

var Dogger = {
    get breed() {
 ? ? ? ?return  "柴犬"
 ? ?}
    set breed(val) {
 ? ? ? ?this._breed_ = val
 ? ?}
}

Dogger.breed = "哈士奇"
Dogger.breed // "哈士奇"

這樣一來(lái),賦值操作就可以改變啦!我們把賦值操作存儲(chǔ)給新建的_breed_ ,只是一種慣例,通過(guò)setter可以改變對(duì)變量訪問(wèn)值的處理規(guī)則。

如果不用_breed_,setter/getter的調(diào)用執(zhí)行時(shí)機(jī)
class Dogger {
    constructor (name, breed) {
        this.name = name;
        this.breed = breed;
    }
    set breed (breed) {
        console.log("setter");
        this.breed = breed;
    }
    get breed () {
        console.log("getter");
        return this.breed;
    }
}

var dogger = new Dogger("忠犬八公", "柴犬");

代碼報(bào)錯(cuò)了!!!這是因?yàn)椋跇?gòu)造函數(shù)中執(zhí)行this.breed = breed的時(shí)候,就會(huì)去調(diào)用set breed,在set breed方法中,我們又執(zhí)行this.breed = breed,進(jìn)行無(wú)限遞歸,最后導(dǎo)致棧溢出(RangeError)

因此,原來(lái)只要this.breed中的屬性名和set breed/get breed后面的breed一致,對(duì)this.breed就會(huì)調(diào)用setter/getter,也就是說(shuō)setter/getter是hook函數(shù),而真實(shí)的存儲(chǔ)變量是_breed_,我們可以在代碼中直接獲取它。

ES6 的 proxy

Proxy可以理解成代理代辦,在目標(biāo)對(duì)象之前架設(shè)一層“攔截”,劫持了外界對(duì)該對(duì)象的訪問(wèn)和設(shè)置(setter和getter)。

借用最近看到的例子直接看代碼吧

const phoneHandler = {
      get (target,name) {
        console.log(`正在讀取${name}`)
        //"0102101220".replace(/(d{3})(d{3})(d{4})/,"$1-$2-$3")
        //"010-210-1220"
        return target[name].replace(/([0-9]{3})(d{3})(d{4})/,"($1)-$2-$3")
      },

      set (target, name, value) {
        console.log(`正在設(shè)置${name}`)
        // .match正則表達(dá)式的方法:匹配所有數(shù)字,全局匹配
        target[name] = value.match(/[0-9]/g).join("")
      }
    }

    // 攔截對(duì)象,代理代辦,對(duì)空對(duì)象的代理
    // 復(fù)雜對(duì)象 ajax 將代碼放在proxy中
    const phoneNumber = new Proxy({}, phoneHandler)
    phoneNumber.phone = "電話:0102101220"
    console.log(phoneNumber.phone)

不難看出new出來(lái)的Proxy是對(duì)空對(duì)象的代理,這樣一來(lái),setter和getter都被phoneHandler中的set和get包辦了,用于復(fù)雜對(duì)象, ajax, 將代碼放在proxy中代理。

參考

你不知道的javascript

javascript高級(jí)程序設(shè)計(jì)

求star:https://github.com/renjie1996...

qq:2578370399

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

轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/82999.html

相關(guān)文章

  • Vue入門--基礎(chǔ)語(yǔ)法

    摘要:在模板中放入太多的邏輯會(huì)讓模板過(guò)重且難以維護(hù)。它會(huì)根據(jù)控件類型自動(dòng)選取正確的方法來(lái)更新元素。指令需要使用的語(yǔ)法,指的是原數(shù)據(jù)數(shù)組,指的是迭代的數(shù)組元素。 注:本教程所使用的vue版本為 2.5.16 MVC與MVVM MVC(Model-View-Controller): M指的是從后臺(tái)獲取到的數(shù)據(jù), V指的是顯示動(dòng)態(tài)數(shù)據(jù)的html頁(yè)面, C是指響應(yīng)用戶操作、經(jīng)過(guò)業(yè)務(wù)邏輯處理后去更新...

    haoguo 評(píng)論0 收藏0
  • Vue 基礎(chǔ)語(yǔ)法

    摘要:在生成的項(xiàng)目中,我們打開(kāi)文件夾下組件,為便于演示,刪減了一部分內(nèi)容本文中的例子都將改造組件來(lái)演示語(yǔ)法一創(chuàng)建組件在中,有好幾種方式用來(lái)創(chuàng)建組件,后面會(huì)單獨(dú)寫(xiě)一篇文章來(lái)介紹。表達(dá)式插值中也支持表達(dá)式插值用雙大括號(hào)將表達(dá)式括起來(lái)。 Vue 的官方文檔寫(xiě)的非常棒(另一個(gè)我覺(jué)得中文文檔寫(xiě)的很好地是 Ant-Design)。 這篇文章以使用 vue-cli 生成的項(xiàng)目為基礎(chǔ),以完整 demo 的...

    saucxs 評(píng)論0 收藏0
  • Vue.js基礎(chǔ)詳解

    摘要:指令帶有前綴,以表示它們是提供的特殊屬性。最后,我們需要為賦值世界舞王尼古拉斯趙四世界舞王尼古拉斯趙四初學(xué)就到這里了,相信你已經(jīng)在腦子里確定了的原理的概念也已經(jīng)非常清楚了,希望你能夠在學(xué)習(xí)的道路上越走越遠(yuǎn),最后感謝你的瀏覽。 vue.js vue介紹 Vue.js(讀音 /vju?/,類似于 view) 是一套構(gòu)建用戶界面的漸進(jìn)式框架。與其他重量級(jí)框架不同的是,Vue 采用自底向上增量...

    omgdog 評(píng)論0 收藏0
  • 后端開(kāi)發(fā)者的Vue學(xué)習(xí)之路(一)

    摘要:如果我們作為一個(gè)后端開(kāi)發(fā)者想掌握一個(gè)前端框架,是一個(gè)好選擇,因?yàn)樗銐虻囊讓W(xué)。是語(yǔ)言的下一代標(biāo)準(zhǔn)。數(shù)據(jù)方法生命周期鉤子函數(shù)其他有些內(nèi)容比較重要,留到后面講定義數(shù)據(jù)定義數(shù)據(jù)定義了數(shù)據(jù),那么就可以在管理的區(qū)域中使用的獲取數(shù)據(jù)的語(yǔ)法來(lái)獲取數(shù)據(jù)。目錄 前言: iview組件庫(kù)示例 element組件庫(kù)示例 ...

    番茄西紅柿 評(píng)論0 收藏0
  • JavaScript 進(jìn)階之深入理解數(shù)據(jù)雙向綁定

    摘要:當(dāng)我們的視圖和數(shù)據(jù)任何一方發(fā)生變化的時(shí)候,我們希望能夠通知對(duì)方也更新,這就是所謂的數(shù)據(jù)雙向綁定。返回值返回傳入函數(shù)的對(duì)象,即第一個(gè)參數(shù)該方法重點(diǎn)是描述,對(duì)象里目前存在的屬性描述符有兩種主要形式數(shù)據(jù)描述符和存取描述符。 前言 談起當(dāng)前前端最熱門的 js 框架,必少不了 Vue、React、Angular,對(duì)于大多數(shù)人來(lái)說(shuō),我們更多的是在使用框架,對(duì)于框架解決痛點(diǎn)背后使用的基本原理往往關(guān)注...

    sarva 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<