JavaScript Object Literal - 如何将“this”关键字替换为另一件事

JavaScript Object Literal - how to replace `this` keyword for another thing

提问人:zokk7 提问时间:7/28/2023 最后编辑:Peter Seligerzokk7 更新时间:8/3/2023 访问量:106

问:

有没有办法避免经常使用关键字来访问当前对象的属性和方法?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>
绑定 对象文字 JavaScript 方法

评论

1赞 zokk7 7/28/2023
这是一个问题,因为我怎样才能避免经常使用关键字,并替换更短的内容。或者干脆不使用。example 2this
0赞 Mister Jojo 7/28/2023
Javascript 是一种刻意精简的对象语言,对于初学者来说已经足够复杂了。其语法的所有改进都趋向于简化;如果您有建议,我很想阅读它,但我警告您已经尝试了很多,并且排除了操作员重载之类的事情。
3赞 evolutionxbox 7/28/2023
我想我只是不明白为什么使用不好?this
0赞 evolutionxbox 7/29/2023
既然是静态的,为什么不使用呢?fruitsfruits.printApple() ...

答:

0赞 jagmitg 7/28/2023 #1

使用多种语言是不可避免的。尤其是当您需要访问同一对象的属性或方法时。this

thiskeyword 是每个执行上下文获取的特殊变量,由 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());

评论

0赞 zokk7 7/28/2023
但是如果我有多个 AS、等......我需要在所有这些中声明这个“var self = this;”?没有别的办法了吗?printAll()printAll_1()printAll_2()
1赞 evolutionxbox 7/28/2023
@Edgaras我上面给出的链接,stackoverflow.com/questions/4616202/...... 应该会有所帮助。另外,使用有什么问题?this
0赞 zokk7 7/28/2023
@evolutionxbox,因为这个不美观且不可读的代码:imgur.com/WJ7pzxP
0赞 Peter Seliger 7/28/2023
@Edgaras......在这种情况下,OP 可以写入 的每个方法,然后像 一样重新绑定它,以便只使用/调用方法名称,但每个方法名称都在其正确的上下文中。let { elm, Element_Create, Element_Declare /* ... */ } = this;thiselm = elm.bind(this); Element_Create = Element_Create.bind(this); /* ... */
1赞 Alexander Nenashev 7/29/2023 #2

似乎最惯用和最简单的方法是使用函数构造函数(硬对象)。实际上,我更喜欢它而不是原型,它非常适合 mixin 设计模式。

关于您的问题 - 不存在很好的对象文字替代品,但您可以使用匿名构造函数:

const obj = new function(){
  // your constructor here
};

还针对原型在数千个对象上进行了测试,在大多数情况下,性能差异可以忽略不计。

另一个好处是,您不再关心正确的绑定,并且可以安全地传递方法引用,因为绑定发生在构造函数中。thisthis

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>

评论

1赞 zokk7 7/30/2023
const self = Object.assign(this, { printAll });对于我的整个项目来说,这是一个不错的选择。TY 感谢您的宝贵帮助,这是我的问题的真正建设性答案/解决方案。
2赞 Peter Seliger 7/29/2023 #3

由于 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; }

评论

0赞 zokk7 7/30/2023
TY 为您的解决方案,以及为 JS 社区提供的建设性解释。