sindresorhus / eslint-plugin-unicorn

More than 100 powerful ESLint rules
MIT License
4.27k stars 367 forks source link

Rule proposal: no-this-in-object-expression #2431

Open axetroy opened 2 months ago

axetroy commented 2 months ago

Description

It is unsafe to use this in an object's properties

It may contain potential bugs

const obj = {
  name: 'foo',
  foo() {
    return this.name
  }
}

obj.foo() // 'foo'

const foo = obj.foo;

foo() // ''

Fail

const obj = {
  name: 'foo',
  foo() {
    return this.name
  }
}

Pass

const obj = {
  name: 'foo',
  foo() {
    return obj.name
  }
}

Proposed rule name

no-this-in-object-expression

Additional Info

No response

fisker commented 2 months ago

I'm not sure about this, it common pattern, and most time, it mean to used as method call, the problem is not how the object defined, but how it's used.

Wish we have bind operator.

fregante commented 2 months ago

I don’t think it’s any less safe than using it in classes. A class method obj.foo is indistinguishable from an object property obj.foo, so in both cases one has to be aware of this.

There’s some merit to avoiding this in objects, I think, but then there’s also situations where people might want to use this and explicitly bind the function, like obj.getName.call(user)

I can’t say I used any of these patterns in a very long time though.

fisker commented 1 month ago

How about no-method-destructuring?

Forbid destructure a method without .bind()

// Bad
const foo = obj.foo;

// Good
const foo = obj.foo.bind(obj)

// Good
const foo = (...args) => obj.foo(...args)