[英]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.