0

我一直在查看 jQuery 插件的插件样板,我觉得没问题,但是设计中有一个主要缺陷,或者可能只是我无法弄清楚的东西。

当我现在编写插件时,我很容易定义只有插件才能访问的公开公开的方法和私有方法。

当我试图在样板中做类似的事情时,我被挫败了。

;(function ( $, window, document, undefined ) {

// Create the defaults once
var 
    pluginName = "defaultPluginName",
    defaults = {
        propertyName: "value"
    };

// The actual plugin constructor
function Plugin ( element, options ) {
        this.element = element;
        this.settings = $.extend( {}, defaults, options );
        this.defaults = defaults;
        this.name = pluginName;
        this.init();
}

Plugin.prototype.init = function() {
    console.log('init')
    console.log(this)
    this.yourOtherFunction();
}
Plugin.prototype.yourOtherFunction = function () {
    console.log('yourOtherFunction')
    console.log(this)
    this.yourOtherFunction2();
}
Plugin.prototype.yourOtherFunction2 = function () {
    privateFunction().bind(this)
}

var privateFunction = function() {
    console.log('private')
    console.log(this)
}   

// A really lightweight plugin wrapper around the constructor,
// preventing against multiple instantiations
$.fn[ pluginName ] = function ( options ) {
    return this.each(function() {
        if ( !$.data( this, "plugin_" + pluginName ) ) {
            $.data( this, "plugin_" + pluginName, new Plugin( this, options ) );
        }
    });
};

})( jQuery, window, document );

$(document).defaultPluginName()

无论如何,您可以看到函数“privateFunction”的范围是窗口对象,但我想要做的是将其范围限定为插件实例,或者基本上是原型方法中的“this”。

我不想做的是将作用域作为函数参数传递给每个私有函数!

那么如何绑定范围呢?

Console output

init
Plugin { element=document, settings={...}, defaults={...}, more...}
yourOtherFunction
Plugin { element=document, settings={...}, defaults={...}, more...}
private
Window index.html <-- I want Plugin, not window 
4

2 回答 2

3

您正在调用privateFunction然后绑定为其this结果的范围。
所以使用(如@Khanh_TO所说):

Plugin.prototype.yourOtherFunction2 = function () {
    privateFunction.apply(this,arguments);
}

代替:

Plugin.prototype.yourOtherFunction2 = function () {
    privateFunction().bind(this)
}

更多细节:

bind在应用您传入的范围(在您的情况下)之后,返回调用函数的副本(在您的情况下为结果)。什么是这样的:privateFunctionthisbind

Function.prototype.bind = function(scope) {
    var _function = this;
    var _args = [];
    for (var i = 0, len = arguments.length-1; i < len; i++){ _args[i] = arguments[i+1]; }
    return function() {
        // returns the same function on which is called (not the same Function object, but
        // another with same properties) with 'this' equal to the first parameter and
        // the remaining specified parameters as parameters of the function returned
        return _function.apply(scope, _args);
        }
}

例如。myFunction.bind(newScope, param1, param2, ...)-> 返回一个匿名函数,该函数又返回myFunction(param1, param2,....)带有 set的函数this = newScope
因此,作为概念证明,这段代码也可以工作:

Plugin.prototype.yourOtherFunction2 = function () {
    privateFunction.bind(this)();
}

但是你应该使用第一个,因为最后一个对额外的段落做同样的事情。

于 2013-12-12T15:34:54.317 回答
2

代替:

Plugin.prototype.yourOtherFunction2 = function () {
    privateFunction().bind(this)
}

Plugin.prototype.yourOtherFunction2 = function () {
    privateFunction.apply(this,arguments);
}
于 2013-10-26T03:49:36.027 回答