22 javascript variables properties
我觉得这很简单,
是否有一种简单的方法为属性添加辅助名称(我认为这是特定于字符串的 - 我不确定),即,
c = length // this line pseudo code
'hello world'.length // returns 11
'hello world'.c // this line is pseudo code, meant to return 11
Run Code Online (Sandbox Code Playgroud)
在上面的示例中,为属性长度创建了一个别名.这可以用JavaScript吗?
Li3*_*357 37
1.带括号表示法
使用括号表示法,您可以访问该属性,如下所示:
'hello world'[c]
Run Code Online (Sandbox Code Playgroud)
这做同样的事情'hello world'.length,如果c是'length'作为一个字符串.
var c = 'length';
console.log('hello world'[c]);Run Code Online (Sandbox Code Playgroud)
唯一的区别是属性是一个字符串.括号表示法是属性访问者.
随着 Object.defineProperty()
现在,如果你想要一个别名:
Object.defineProperty(String.prototype, 'c', {
get: function() {
return this.length;
}
});
console.log("hello world".c);Run Code Online (Sandbox Code Playgroud)
上面用于 Object.defineProperty定义现有对象String的prototype对象的属性.这样,字符串的所有实例都将具有此新属性.根据文件:
该
Object.defineProperty()方法直接在对象上定义新属性,或修改对象上的现有属性,并返回该对象.句法
Object.defineProperty(obj, prop, descriptor)
obj要修改的对象在哪里,prop是新属性还是现有属性,并且descriptor是新属性或现有属性的描述符.
因此,上面定义了String.prototype具有名称的对象的属性c.它的描述符是一个返回长度的get函数this.在上面的示例中,this引用字符串,以便返回字符串的长度.你可以阅读更多关于干将这里.
也可以通过更改为适用的prototype(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 12Run Code Online (Sandbox Code Playgroud)
当属性定义没有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) //15Run Code Online (Sandbox Code Playgroud)
只要设置了别名(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) // 20Run Code Online (Sandbox Code Playgroud)
这允许您默认别名/目标值,直到另行更新.与只读的情况不同,您可以更改别名/目标值,但与同步不同,当您更改别名时,不更新源 - 而是别名变为常规值.
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) // 20Run Code Online (Sandbox Code Playgroud)