在对象方法上使用.call()不会传递上下文

时间:2017-06-19 12:56:09

标签: javascript jquery jquery-ui

我正在尝试调用JQuery UI小部件的“自定义”方法,并传入this / self / context以进行测试。但是上下文没有传递给方法。当我从方法this

中检查undefined

简短的例子是我使用以下代码调用该方法:

widget.myWidget('option', "classChangeCallback").call(widget);

当我从this内部检查classChangeCallback时,它是undefined。以下是您可以复制的问题示例。

(function ($) {

  $.widget( "MY_NAMESPACE.myWidget", {

  	options: {

  		classChangeCallback: function() {
 
  			// When this callback is called via click evt: this.element is defined
  			// When this callback is called using .call, .apply: this.element is undefined
  			console.log(this.element);
			
			var newEle = $('<div><p>New Element</p></div>')
				.appendTo(this.element)

			return newEle;
		}
	},

	_create: function () {

		this._super( "_create" );

		// Bind to click event as an example only: in my project this 
		// callback is actually called when an elements classes change
		this.element.click(this.options.classChangeCallback.bind(this));
	},

  });

})(jQuery);



// .............

$(document).ready(function() {

	var widget = $('[data-type="foo"]').myWidget();

	// In my testing I want to call the function to test it
	widget.myWidget('option', "classChangeCallback").call(widget);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.2.3/jquery.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.css" rel="stylesheet"/>

<div data-type="foo" style="min-height:100px; background-color: green;">
		
		<p>
			Bar
		</p>
</div>

1 个答案:

答案 0 :(得分:1)

$(selector).myWidget()返回用于链接的jQuery对象。

因此,在行widget.myWidget('option', "classChangeCallback").call(widget);中,您将传递jQuery对象作为上下文,而不是成员名称所暗示的窗口小部件实例。

虽然这很麻烦,但你可以尝试:

widget.myWidget('option', "classChangeCallback").call(widget.myWidget("instance"));

但我不禁想到你可能会更好地建立/触发自定义事件。正如文档中所述,

  

_on()方法提供了直接事件绑定的几个好处:   

  • 在处理程序中保持适当的上下文。
  •   
  • ...