簡體   English   中英

在JavaScript中為屬性添加別名

[英]Add an alias for a property in JavaScript

我覺得這很簡單,

是否有一種簡單的方法為屬性添加輔助名稱(我認為這是特定於字符串的 - 我不確定),即,

c = length // this line pseudo code

'hello world'.length // returns 11
'hello world'.c      // this line is pseudo code, meant to return 11

在上面的示例中,為屬性長度創建了一個別名。 這可以用JavaScript嗎?

1.帶括號表示法

使用括號表示法 ,您可以訪問該屬性,如下所示:

'hello world'[c]

這與'hello world'.length的作用相同,如果c'length'作為字符串。

 var c = 'length'; console.log('hello world'[c]); 

唯一的區別是屬性是一個字符串。 括號表示法是屬性訪問者。

2.使用Object.defineProperty()

現在,如果你想要一個別名:

 Object.defineProperty(String.prototype, 'c', { get: function() { return this.length; } }); console.log("hello world".c); 

上面使用Object.defineProperty來定義現有對象String的prototype對象的屬性。 這樣,字符串的所有實例都將具有此新屬性。 根據文件:

Object.defineProperty()方法直接在對象上定義新屬性,或修改對象上的現有屬性,並返回該對象。

句法

Object.defineProperty(obj, prop, descriptor)

其中obj是要修改的對象, prop是新屬性或現有屬性, descriptor是新屬性或現有屬性的描述符。

因此,上面定義了String.prototype對象的屬性,名稱為c 它的描述符是get函數返回的長度this 在上面的示例中, this指的是字符串,因此它返回字符串的長度。 你可以在這里閱讀更多關於吸氣劑的信息


這也可以通過更改為適用的原型( obj )來定義更多類型,例如使用Object.prototype 然而,這有潛在的問題,因為試圖返回this.length對象上沒有一個長度屬性將返回undefined,因為看到這里 您還可以使用Object.defineProperties定義多個屬性。

為了擴展@ AndrewLi的答案,你可以用Object.defineProperty()做一些類似別名的事情。

  • 只讀別名(與他的答案相同)
  • 同步別名在修改后修改源
  • 默認別名讀取或“默認為”源直到更改(此時關系被破壞)

我將它們編寫為將對象與屬性, sProp和具有屬性tProp目標對象相關聯的函數 源和目標可以是同一個對象(允許屬性作為同一對象上另一個屬性的別名),但這不是必需的。 此外,源(或目標)可以是原型(如Object.prototype,String.prototype等)。

“正常”分配

這個不是別名,也不是使用Object.defineProperty() 為目標分配源的VALUE ,而不是對它的引用。 這意味着當源更改時,目標不會。

 function assign(target, tProp, source, sProp) { target[tProp] = source[sProp]; return target; } let myTarget = {} let mySource = {b: 12} myTarget = assign(myTarget, 'a', mySource, 'b') // "alias" was assigned source value console.log('"alias":',myTarget.a) // 12 // changes to source independent of "alias" mySource.b = 13 console.log("source:", mySource.b) // 13 console.log('"alias":', myTarget.a) // still 12 

只讀別名(以上解決方案)

當屬性定義沒有setter時,它實際上是一個只讀值。 對source屬性的更改將反映在別名中; 但是,您無法設置別名的值。

 function read(target, tProp, source, sProp){ Object.defineProperty(target, tProp, { enumerable: true, configurable: true, get(){ return source[sProp]; } }) return target; } let myTarget = {} let mySource = {b: 12} myTarget = read(myTarget, 'a', mySource, 'b') // Alias gets value from source console.log("alias:", myTarget.a) // 12 // No setter effectively means read-only myTarget.a = 15 console.log("alias:", myTarget.a) // 12 // Changes to source are seen in target mySource.b = 15 console.log("source:", mySource.b) //15 console.log("target:", myTarget.a) //15 

同步別名

只要設置了別名(target)屬性,此別名就會修改上面的只讀版本以設置source屬性。 通過這種方式,源和目標始終保持同步。

 function sync(target, tProp, source, sProp){ Object.defineProperty(target, tProp, { enumerable: true, configurable: true, get(){ return source[sProp]; }, set(value){ source[sProp] = value; } }) return target; } let myTarget = {} let mySource = {b: 12} myTarget = sync(myTarget, 'a', mySource, 'b') // Alias gets value from source console.log("alias:", myTarget.a) // 12 // Changing alias' value modifies the source myTarget.a = 15 console.log("alias:", myTarget.a) // 15 console.log("source:", mySource.b) // 15 // Changing source modifies alias still mySource.b = 20 console.log("source:", mySource.b) // 20 console.log("alias:", myTarget.a) // 20 

別名為默認值

這允許您默認別名/目標值,直到另行更新。 與只讀的情況不同,您可以更改別名/目標值,但與同步不同,當您更改別名時,不更新源 - 而是別名變為常規值。

 function setDefault(target, tProp, source, sProp){ Object.defineProperty(target, tProp, { enumerable: true, configurable: true, get(){ return source[sProp]; }, set(value){ delete target[tProp]; target[tProp] = value; } }) return target; } let myTarget = {} let mySource = {b: 12} myTarget = setDefault(myTarget, 'a', mySource, 'b') // Alias gets value from source console.log('alias:', myTarget.a) // 12 // Changing source modifies alias still mySource.b = 15 console.log('source:', mySource.b) // 15 console.log('alias:', myTarget.a) // 15 // Changing alias' value DOES NOT modify source myTarget.a = 20 console.log("alias:", myTarget.a) // 20 console.log("source:", mySource.b) // 15 // The relationship between source and alias is BROKEN mySource.b = 100 console.log("source:", mySource.b) // 100 console.log("alias:", myTarget.a) // 20 

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM