将论证传递给lodash _.result

时间:2015-12-30 11:52:29

标签: javascript arguments lodash

有没有办法将参数传递给lodash _.result,对于这种情况,第二个属性是方法名称?或者有替代方法(最好是lodash)吗?

用法示例可能是这样的:

var object = {
  'cheese': 'crumpets',
  'stuff': function( arg1 ) {
    return arg1 ? 'nonsense' : 'balderdash';
  }
};

_.result(object, 'cheese');
// => 'crumpets'

_.result(object, 'stuff', true);
// => 'nonsense'

_.result(object, 'stuff');
// => 'balderdash'

谢谢。

4 个答案:

答案 0 :(得分:2)

我查看了lodash _.result函数的源代码,但没有支持。您可以为此实现自己的功能,并使用_。mixin扩展lodash。

function myResult(object, path, defaultValue) {
    result = object == null ? undefined : object[path];
    if (result === undefined) {
        result = defaultValue;
    }
    return _.isFunction(result) 
        ? result.apply(object, Array.prototype.slice.call( arguments, 2 )) 
        : result;
}

// add our function to lodash
_.mixin({ myResult: myResult})


_.myResult(object, 'cheese');
// "crumpets"

_.myResult(object, 'stuff', true);
// "nonsense"

_.myResult(object, 'stuff');
// "balderdash"

答案 1 :(得分:1)

你可以创建自己的mixin。这是一个使用即将发布的lodash 4.0.0的例子



var reIsDeepProp = /\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/;
var reIsPlainProp = /^\w*$/;
var rePropName = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]/g;
var reEscapeChar = /\\(\\)?/g;

function isKey(value, object) {
  if (typeof value == 'number') {
    return true;
  }
  return !_.isArray(value) &&
    (reIsPlainProp.test(value) || !reIsDeepProp.test(value) ||
      (object != null && value in Object(object)));
}

function stringToPath(string) {
  var result = [];
  _.toString(string).replace(rePropName, function(match, number, quote, string) {
    result.push(quote ? string.replace(reEscapeChar, '$1') : (number || match));
  });
  return result;
}

function baseToPath(value) {
  return _.isArray(value) ? value : stringToPath(value);
}

function parent(object, path) {
  return path.length == 1 ? object : _.get(object, _.slice(path, 0, -1));
}

function customResult(object, path, args, defaultValue) {
  if (!isKey(path, object)) {
    path = baseToPath(path);
    var result = get(object, path);
    object = parent(object, path);
  } else {
    result = object == null ? undefined : object[path];
  }
  if (result === undefined) {
    result = defaultValue;
  }
  return _.isFunction(result) ? result.apply(object, _.isArrayLike(args) ? args : []) : result;
}

_.mixin({
  'customResult': customResult
});

var object = {
  'cheese': 'crumpets',
  'stuff': function(arg1) {
    return arg1 ? 'nonsense' : 'balderdash';
  }
};

var out = document.getElementById('out');
out.textContent = _.customResult(object, 'cheese') + '\n';
// => 'crumpets'

out.textContent += _.customResult(object, 'stuff', [true]) + '\n';
// => 'nonsense'

out.textContent += _.customResult(object, 'stuff') + '\n';
// => 'balderdash'

<script src="https://rawgit.com/lodash/lodash/master/lodash.js"></script>
<pre id="out"></pre>
&#13;
&#13;
&#13;

我已经使用了lodash内部工作的确切函数,但是你可以用暴露的方法来完成它。如果我有几分钟的时间,我会看看是否有可能。

仅使用暴露方法的问题是我没有看到任何方法来执行具有正确上下文的函数。

  

此方法与_.get类似,不同之处在于,如果已解析的值为a   函数它的父对象和它的绑定调用   结果返回。

答案 2 :(得分:1)

这是另一个mixin实现:

function myResult(obj, path, defaultValue) {

    // Find any arguments beyond what's normally
    // passed to result().
    var args = _.drop(arguments, 3);

    // We need to know upfront whether or not this
    // is a function we're dealing with.
    var isFunc = _.isFunction(_.get(obj, path));

    // If this is a function, and there's arguments
    // to apply, then use spread() and bindKey() to
    // return the result of calling the method with arguments.
    // Otherwise, it's just a plain call to result().
    if (isFunc && args.length) {
        return _.spread(_.bindKey(obj, path))(args);
    } else {
        return _.result(obj, path, defaultValue);
    }
}

_.mixin({ myResult: myResult });

我们只需要处理path是函数附加参数的附加案例。否则,我们将恢复为基本的result()实施。

_.myResult(object, 'test');
// → undefined

_.myResult(object, 'test', 15);
// → 15

_.myResult(object, 'cheese', 'wine');
// → "crumpets"

_.myResult(object, 'stuff');
// → "balderdash"

_.myResult(object, 'stuff', null, true);
// → "nonsense"

答案 3 :(得分:0)

您现在可以使用lodash v4 invoke方法执行此操作,但是,如果您尝试调用非函数的东西(未定义的props可以),它将抛出错误:

var object = {
  'cheese': 'crumpets',
  'stuff': function(arg1) {
    return arg1 ? 'nonsense' : 'balderdash';
  }
};

try {
  var rst1 = _.invoke(object, 'cheese');
  // => 'Error!!'
} catch(e) {
  console.log('Error: cheese is not a function.'); 
}

var rst2 = _.invoke(object, 'stuff', true);
console.log(rst2); // => 'nonsense'

var rst3 = _.invoke(object, 'stuff');
console.log(rst3); // => 'balderdash'

var rst4 = _.invoke(object, 'bob');
console.log(rst4); // => 'undefined'
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.js"></script>