2015-12-30 57 views
5

有沒有辦法將參數傳遞給lodash _.result,對於這種情況,當第二個屬性是方法名時?或者是否有替代方法(最好是lodash)呢?將參數傳遞給lodash _.result

用例可能是這樣的:

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

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

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

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

謝謝。

+1

該文檔似乎沒有顯示任何方式來完成此https://lodash.com/docs#result(如果我理解正確),所以我的猜測是,這不支持。您可以在這裏詢問https://github.com/lodash/lodash/issues以確定,或者甚至要求它作爲附加功能。 – Xotic750

回答

1

我看了lodash _.result函數的源代碼,並沒有支持這個。你可以實現你自己的函數,並使用_擴展lodash。 mixin

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" 
+0

感謝您的簡單解決方案! –

+0

請注意,該解決方案不能以多種方式提供'_.result'的全部功能。 – Xotic750

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>

我已經使用了精確的功能從lodash的內部工作,但你可以只用暴露做到這一點方法。如果我有幾分鐘備用,我會看看是否有可能。

只使用公開的方法的問題是,我沒有看到任何方法來執行正確的上下文的功能。

,此方法類似於_.get只是如果解析值是 功能,它與其父對象的這種結合,並返回 其結果調用。

+0

這個想法很明確,謝謝。所以它似乎可以解決更多的一般任務,就像深層次的結果一樣? –

+0

在方法'customResult'中應該是方法'_.get',後來'_.slice'而不是'_slice',我想。 –

+1

是的,這個解決方案和原來的'_.result'一樣工作,它只是在方法中加入'args'參數。 – Xotic750

1

下面是另一個混​​入實現:

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"