2015-09-03 71 views
2

在JavaScript我可以綁定參數,像這樣的功能..使用JavaScript .bind跳過一個參數()方法

function foo(arg1, arg2) { console.log(arguments); } 
foo = foo.bind(this, 'bar'); 

調用時,我們得到如下的輸出...

foo('baz'); 
> { '0': 'bar', '1': 'baz' } 

是否可以跳過.bind()函數中的參數來實現以下輸出?

function foo(arg1, arg2, arg3, arg4) { console.log(arguments); } 
foo = foo.bind(this, 'bar', null, 'qux'); 
foo('baz', 'lel'); 
> { '0': 'bar', '1': 'baz', '2': 'lel', '3': 'qux' } 
+0

我不這麼認爲..如果你不需要這個參數爲什麼通過它 –

回答

0

不,你只是約束null

函數的參數是函數的參數;綁定null的確如此,它不重新定義該函數,它返回一個具有相同簽名的新函數。

+1

「返回一個具有相同簽名的新的」---它實際上是一樣的嗎?如果綁定參數,則新函數的「元數」會減少。 – zerkms

+0

@zerkms是的,我無法弄清楚怎麼說。我的意思是,傳入null不會改變* original *函數的參數。 –

4

看看下劃線的_.partial

部分通過填寫任意數量的它的參數,在不改變其動態此值應用的功能。 您可以在參數列表中傳遞_來指定一個參數,該參數不應該被預先填充,而是在通話時保持開放狀態。

你的情況:

function foo(arg1, arg2, arg3, arg4) { console.log(arguments); } 
foo = _.partial(foo, 'bar', _, 'qux'); 
foo('baz', 'lel'); 
> { '0': 'bar', '1': 'baz', '3': 'qux', '4': 'lel'} 

是的,我知道這是不是你說的正是你想要的。你似乎想這兩個論據被擠在_的地方。有圍繞不是明確指定兩個參數將在調用的時候填寫其他沒有什麼好辦法:

foo = _.partial(foo, 'bar', _, _, 'qux'); 

我並不推薦您使用此,但至少你可以看看他們的代碼並得到一些提示。

如果你想有預定的參數總是在最後,像'qux',你會需要一些額外的機器。例如,這裏有一個小程序(使用ES6,但你能適應),是一種把函數轉換爲在指定的參數被放置在參數列表的末尾:

function partialEnd(fn, ...predefinedArgs) { 
    return function() { 
    return fn.apply(this, [...arguments, ...predefinedArgs]); 
    }; 
} 

您可以使用此類似這樣的:

function foo(arg1, arg2, arg3, arg4) { console.log(arguments); } 
foo = _.partial(foo, 'bar', _, _); 
foo = partialEnd(foo, 'lel'); 

foo('baz', 'lel'); 
> { '0': 'bar', '1': 'baz', '3': 'lel', '4': 'qux'} 

function foo(a, b, c) { console.log(a + b + c); } 
foo = partialEnd(foo, 3); 
foo(1, 2) // outputs 6 

你可以使用_.partial_佔位符,以獲得其中的一些參數插入到參數列表,和其他人總是放在最後的效果結合本

2

沒有這樣的功能存在於JavaScript的,但它是非常簡單的實現,做同樣的事情的函數:

function curryWithNulls(fn, thisObj) { 
    var curriedArgs = Array.prototype.slice.call(arguments, 2); 
    var length = curriedArgs.length; 

    return function() { 
    var args = Array.prototype.slice.call(arguments); 

    for (var i = 0; i < length || args.length; i++) { 
     if (i >= length || curriedArgs[i] === null) { 
     curriedArgs[i] = args.shift(); 
     } 
    } 
    return fn.apply(thisObj, curriedArgs); 
    } 
} 

function foo(arg1, arg2, arg3, arg4) { 
    console.log(arguments); 
} 

var curriedFoo = curryWithNulls(foo, this, 'bar', null, null, 'qux'); 
curriedFoo('baz', 'lel'); 
// => { '0': 'bar', '1': 'baz', '2': 'lel', '3': 'qux' } 

這從你的例子稍有不同,它需要一個null每個跳過參數(而在你的例子中,你有一個單獨的null填充兩個參數)。這允許與咖喱參數更復雜的結構在任何位置,例如:

var curriedFoo2 = curryWithNulls(foo, this, null, 'bar', null, 'qux'); 
curriedFoo2('baz', 'lel'); 
// => { '0': 'baz', '1': 'bar', '2': 'lel', '3': 'qux' } 
0

這是可能具有功能組合物:

var foo = function(arg1, arg2, arg3, arg4) { console.log(arguments); } 
var bar = function(arg2, arg4) { 
    return foo.bind(this, 'bar', arg2, 'qux')(); 
} 
bar('baz', 'lel'); 

或,隨着現代的語法:

const foo = (arg1, arg2, arg3, arg4) => console.log(arguments); 
const bar = (arg2, arg4) => foo.bind(this, 'bar', arg2, 'qux')(); 
bar('baz', 'lel'); 

或完全沒有束縛:

const foo = (arg1, arg2, arg3, arg4) => console.log(arguments); 
const bar = (arg2, arg4) => foo(this, 'bar', arg2, 'qux', arg4); 
bar('baz', 'lel'); 

P.S.不要忘記調用你的綁定函數(綁定後注意這些());