如何 curry jQuery 方法——哪个`this`值将传递 jQuery 对象?
Posted
技术标签:
【中文标题】如何 curry jQuery 方法——哪个`this`值将传递 jQuery 对象?【英文标题】:How to curry jQuery methods -- which `this` value will pass the jQuery object? 【发布时间】:2016-04-29 23:35:59 【问题描述】:如果我想使用 Function.prototype.bind
创建一个 jQuery 函数,即需要一个包装函数,我应该提供哪个 this
值?以下简单示例似乎不起作用:
// e.g.: $.fn.outerHeight() with argument true gets height including margin
$.fn.marginBoxHeight = $.fn.outerHeight.bind($.fn, true);
$.fn
是 this
参数的错误选择。它应该是什么,以便函数可以访问 jQuery 内部方法(如果需要)?
【问题讨论】:
javascriptissexy.com/… 通常在 jQuery 中你不引用或咖喱,你做的更像是$.fn.marginBoxHeight = function() return this.outerHeight(true);
谢谢@adeneo 是的,我知道,事实上我就是这样解决问题的——这更像是一个学术问题。我将不得不查看源代码;我猜正确的范围可能是 $.fn.init
或 $.fn.init.prototype
@lunelson 在这种情况下,学术上的答案可能是“放弃 jQuery,越快越好”。
不可能:this
应该是您调用marginBoxHeight
的对象,您事先并不知道。所以,你不能使用bind
。
【参考方案1】:
jQuery.proxy
执行柯里化如下:
QUnit.test( "jQuery.proxy", function( assert )
var thisObject = foo: "bar", method: test ;
// jQuery 1.9 improved currying with `this` object context
fn = function()
assert.equal( Array.prototype.join.call( arguments, "," ), "arg1,arg2,arg3", "args passed" );
assert.equal( this.foo, "bar", "this-object passed" );
;
cb = jQuery.proxy( fn, null, "arg1", "arg2" );
cb.call( thisObject, "arg3" );
);
QUnit.test( "jQuery.proxy", function( assert )
assert.expect( 9 );
var test2, test3, test4, fn, cb,
test = function()
assert.equal( this, thisObject, "Make sure that scope is set properly." );
,
thisObject = foo: "bar", method: test ;
// Make sure normal works
test.call( thisObject );
// Basic scoping
jQuery.proxy( test, thisObject )();
// Another take on it
jQuery.proxy( thisObject, "method" )();
// Make sure it doesn't freak out
assert.equal( jQuery.proxy( null, thisObject ), undefined, "Make sure no function was returned." );
// Partial application
test2 = function( a )
assert.equal( a, "pre-applied", "Ensure arguments can be pre-applied." );
;
jQuery.proxy( test2, null, "pre-applied" )();
// Partial application w/ normal arguments
test3 = function( a, b )
assert.equal( b, "normal", "Ensure arguments can be pre-applied and passed as usual." );
;
jQuery.proxy( test3, null, "pre-applied" )( "normal" );
// Test old syntax
test4 = "meth": function( a )
assert.equal( a, "boom", "Ensure old syntax works." );
;
jQuery.proxy( test4, "meth" )( "boom" );
// jQuery 1.9 improved currying with `this` object
fn = function()
assert.equal( Array.prototype.join.call( arguments, "," ), "arg1,arg2,arg3", "args passed" );
assert.equal( this.foo, "bar", "this-object passed" );
;
cb = jQuery.proxy( fn, null, "arg1", "arg2" );
cb.call( thisObject, "arg3" );
);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<link rel="stylesheet" href="https://code.jquery.com/qunit/qunit-2.4.0.css">
<script src="https://code.jquery.com/qunit/qunit-2.4.0.js"></script>
<div id="qunit"></div>
<div id="qunit-fixture"></div>
最简单的例子是:
var foo = jQuery.proxy(function()return this('html:first'), jQuery)
console.log(foo() )
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
参考文献
jQuery.proxy() | jQuery API Documentation
jquery/core.js at master · jquery/jquery
jQuery Combinators by raganwald
Combinator Recipes for Working With Objects in JavaScript
Ingredients of Effective Functional JavaScript: Closures, Partial Application and Currying
Partial function application for humans | Andrew Berls
Practical Applications of Partial Application
【讨论】:
以上是关于如何 curry jQuery 方法——哪个`this`值将传递 jQuery 对象?的主要内容,如果未能解决你的问题,请参考以下文章