【问题标题】:Best practice when calling self object methods调用 self 对象方法时的最佳实践
【发布时间】:2018-08-01 08:13:10
【问题描述】:

假设我有这个代码:

const MyObject = {
    a($els) {
        // What is the best practice here ?
        $els.each(function() {
            MyObject.b($(this));
        });
        // Or
        const self = this;
        $els.each(function() {
            self.b($(this));
        });
    },
    b($el) {
        $el.addClass('test');
    }
};

在对象中调用另一个方法的“最佳实践”是什么?调用变量“MyObject”有什么缺点吗?还是使用this 更好?为什么?

【问题讨论】:

  • 如果您将来将MyObject 重命名为其他名称怎么办?如果您采用第一种方法,则必须在两个地方进行更改。
  • 好吧this 会让它更可重用..
  • 只使用 this.b(x) ?
  • 为什么self = this...?!
  • 这里看起来有点荒谬:a(x) === b(x),那么这种模式真的有用例吗?

标签: javascript jquery object this


【解决方案1】:

没有错

this.method(params)

但是,如果您有嵌套范围,this 可能意味着不同的东西,并且很快就会让人感到困惑。为避免这种情况,请使用var self = this 创建另一个指向右侧的变量this

例子:

const MyObject = {
    a(x) {
        var self = this;
        return x.map(function (a) 
        {
           // cannot use this here to access parent scope
           return self.b(a);
        })


    },
    b(y) {
      return y % 2;
    }

};

【讨论】:

  • 丢失this 的更优雅的解决方案是x.map(a => this.b(a))...
  • 我想使用this 确实是最佳实践,但因此我在大多数函数的开头使用const self = this;。这个“代码重复”是我问的原因^^
【解决方案2】:

你不需要 jQuery。没有它,this 问题可以像这样避免(双关语;)。如果你真的需要 jQuery,请参阅 sn-p 的第二部分了解我的看法。

const MyObject = {
    getAll: selector => Array.from(document.querySelectorAll(selector)),
    addClass:  (elements, className) => 
      elements.forEach(element => element.classList.add(className)),
};

MyObject.addClass(MyObject.getAll("[data-test]"), "test");
setTimeout(() => 
  MyObject.addClass(MyObject.getAll("[data-test2]"), "test2"), 1000);
  
// using jQuery I'd use
const MyObjectJQ = {
  setClass4Elements($els) {
    const setClass = this.setClass2Foo;
    $els.each( (i, elem) => setClass($(elem)) );
  },
  setClass2Foo($el) {
    $el.addClass('foo');
  }
};

setTimeout(() => 
  MyObjectJQ.setClass4Elements($("[data-test2]")), 2000);

// still I'd avoid  the use of [this]
const MyObjectJQNoThis = {
  setClass4Elements($els, className) {
    const setClass = $el => $el.addClass(className);
    $els.each( (i, elem) => setClass($(elem)) );
  }
};

setTimeout(() => 
  MyObjectJQNoThis.setClass4Elements($("[data-test]"), "bar"), 3000);
.test {
  color: red;
}
.test2 {
  color: green;
}
.foo {
  color: orange;
}
.bar {
  color: grey;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div data-test>div1</div>
<div data-test2>div2</div>
<div data-test>div3</div>
<div data-test2>div4</div>

【讨论】:

  • 我在示例中使用了 jQuery,因为我实际上正在编写一个 jQuery 插件。但是有很多非 jQuery 的情况,this 的值可以改变(回调,循环)。
【解决方案3】:

我认为您对类和对象之间的区别感到困惑。 MyObject 是指 MyObject 的类。 this 关键字引用对象的一个​​实例。我猜你想要完成后者,这个关键字就是你想要使用的。

【讨论】:

  • MyObject 不是类/构造函数,它是一个普通对象。
猜你喜欢
  • 2013-02-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-01-20
  • 2010-10-14
  • 1970-01-01
  • 2013-09-23
  • 1970-01-01
相关资源
最近更新 更多