eslint-plugin-lodash icon indicating copy to clipboard operation
eslint-plugin-lodash copied to clipboard

feature: prefer-invoke

Open nirnaor opened this issue 8 years ago • 6 comments

In many places there are usages of _.isFunction before running a certain function. _.invoke does exactly that. The rule will prefer using _.invoke instead of checking if something is a function before executing it

Examples

Bad

// This is bad
if (_.isFunction(obj.foo)) {
    obj.foo(a, b, c)
}

Good

// This is good
_.invoke(obj, 'foo', a, b, c)

When using !_isFunction in order to raise an exception, the rule should pass

// this is alright
if (!_.isFunction(obj, 'foo') {
   throw new Error('foo is not a function')
}

nirnaor avatar Aug 08 '17 12:08 nirnaor

@nirnaor looks OK, feel free to open a PR. Things to make sure:

  • The function/method call is the only statement in the if block
  • This should warn both on function calls and method calls (e.g. both f(a, b, c) and x.f(a, b, c)

ganimomer avatar Aug 08 '17 12:08 ganimomer

Hey @ganimomer Just making sure that I understood your notes:

First note:

Good
// This is good.
if(_.isFunction(obj.foo) {
  obj.foo();
  console.log('calling foo')
}

Second note

Bad

var f = () => console.log('i am a function')
// This is bad.
if(_.isFunction(f)){
  f()
}

nirnaor avatar Aug 08 '17 12:08 nirnaor

Exactly. (Also, you can use these examples in the docs)

ganimomer avatar Aug 08 '17 13:08 ganimomer

Also

// This is bad.
if(shouldRender && _.isFunction(obj.render){
  obj.render()
}
// While this is good.
if(shouldRender{
  _.invoke(obj, 'render');
}

nirnaor avatar Aug 08 '17 13:08 nirnaor

Yeah, I agree. However, the order here matters. This:

if (_.isFunction(f) && someHeavyCalculationThatTakesAWhile(...someArguments)) {
 f()
}

Is not the same as

if (someHeavyCalculationThatTakesAWhile(...someArguments)) {
 _.invoke(f);
}

Especially if this code runs very often.

ganimomer avatar Aug 08 '17 13:08 ganimomer

Also, make sure to check this bad case as well:

if (shouldRender && !shouldSkip && _.isFunction(f)) {
  f();
}

ganimomer avatar Aug 08 '17 13:08 ganimomer