提问人:zokk7 提问时间:7/28/2023 最后编辑:Peter Seligerzokk7 更新时间:8/3/2023 访问量:106
JavaScript Object Literal - 如何将“this”关键字替换为另一件事
JavaScript Object Literal - how to replace `this` keyword for another thing
问:
有没有办法避免经常使用关键字来访问当前对象的属性和方法?this
我尝试了类似的东西,但它根本不起作用。Example 2
示例 1:
<script>
var fruits = {
printApple(){ return "Apple"; },
printBanana(){ return "Banana"; },
printPear(){ return "Pear"; },
printAll(){ return "All Fruits: " + this.printApple() + ", " + this.printBanana() + ", " + this.printPear(); }
}
alert(fruits.printAll());
</script>
示例 2:
(此脚本不起作用,请勿使用)
<script>
var fruits = {
y(){ return this.fruits; },
printApple(){ return "Apple"; },
printBanana(){ return "Banana"; },
printPear(){ return "Pear"; },
printAll(){ return "All Fruits: " + y.printApple() + ", " + y.printBanana() + ", " + y.printPear(); }
}
alert(fruits.printAll());
</script>
答:
使用多种语言是不可避免的。尤其是当您需要访问同一对象的属性或方法时。this
this
keyword 是每个执行上下文获取的特殊变量,由 JS 引擎自动设置。
示例 2 - 脚本不起作用,因为未在全局上下文中定义。y
var fruits = {
printApple(){ return "Apple"; },
printBanana(){ return "Banana"; },
printPear(){ return "Pear"; },
printAll(){
var self = this;
return "All Fruits: " + self.printApple() + ", " + self.printBanana() + ", " + self.printPear();
}
}
alert(fruits.printAll());
评论
printAll()
printAll_1()
printAll_2()
this
let { elm, Element_Create, Element_Declare /* ... */ } = this;
this
elm = elm.bind(this); Element_Create = Element_Create.bind(this); /* ... */
似乎最惯用和最简单的方法是使用函数构造函数(硬对象)。实际上,我更喜欢它而不是原型,它非常适合 mixin 设计模式。
关于您的问题 - 不存在很好的对象文字替代品,但您可以使用匿名构造函数:
const obj = new function(){
// your constructor here
};
还针对原型在数千个对象上进行了测试,在大多数情况下,性能差异可以忽略不计。
另一个好处是,您不再关心正确的绑定,并且可以安全地传递方法引用,因为绑定发生在构造函数中。this
this
function Fruits(){
// add public methods here, use `self` anywhere as a safe alternative for `this`
const self = Object.assign(this, { printAll, alertMe });
function printApple() {
return "Apple";
}
function printBanana() {
return "Banana";
}
function printPear() {
return "Pear";
}
function printAll() {
return "All Fruits: " + printApple() + ", " + printBanana() + ", " + printPear();
}
function alertMe() {
// use `self` if you allow to override the method in a mixin
alert(self.printAll());
}
}
function MixedFruits() {
// call Fruits as a constructor on the current `this`
Fruits.call(this);
Object.assign(this, { printAll });
function printAll(){
return 'printAll() has been overridden!!!';
}
}
const fruits = new Fruits;
console.log(fruits.printAll());
const mixedFruits = new MixedFruits;
// we don't care about `this` when passing methods as arguments
$base.addEventListener('click', fruits.alertMe);
$overridden.addEventListener('click', mixedFruits.alertMe);
<button id="$base">Fruits::alertMe()</button>
<br/>
<br/>
<button id="$overridden">MixedFruits::alertMe()</button>
评论
const self = Object.assign(this, { printAll });
对于我的整个项目来说,这是一个不错的选择。TY 感谢您的宝贵帮助,这是我的问题的真正建设性答案/解决方案。
由于 OP 的真正困境/问题已被 OP 的一些评论所描绘......
“..,因为这个不美观且不可读的代码:imgur.com/WJ7pzxP”——埃德加拉斯
...唯一可以解决此问题的方法是从其上下文中本地访问方法,并将绑定版本重新分配给每个局部变量。this
我上面的评论已经指向了这个方向......
“@Edgaras......在这种情况下,OP 可以写......
let { elm, Element_Create, Element_Declare /* ... */ } = this;
...对于
每种
方法,然后像......
elm = elm.bind(this); Element_Create = Element_Create.bind(this); /* ... */
...以便仅使用/调用方法名称,但每个名称都在其正确的上下文中。
使用OP提供的,已经简化的代码示例,后者应该重写为...
var fruits = {
apple: 'Apple',
pear: 'Pear',
banana: 'Banana',
getApple() { return this.apple; },
getPear() { return this.pear; },
getBanana() { return this.banana; },
printAll() {
// access and assign every needed method from the `this` context.
let { getApple, getPear, getBanana } = this;
// reassign each method by its own bound variant each rebinding `this`.
[getApple, getPear, getBanana] = [getApple, getPear, getBanana]
.map(getter => getter.bind(this));
// invoke the rebound method names without the connecting dot operator.
return `All Fruits: ${ getApple() }, ${ getPear() }, ${ getBanana() }`;
},
};
console.log(
fruits.printAll()
);
.as-console-wrapper { min-height: 100%!important; top: 0; }
评论
example 2
this
this
fruits
fruits.printApple() ...