背景
所以,几个月前我看到了一篇文章Essential jQuery Plugin Patterns 。我正在尝试编写一个简单的 jQuery 插件,我发现这篇文章非常有用。它包含很多信息,其中大部分超出了我对 JavaScript 或 jQuery 的专业知识。主要感兴趣的是第一个插件模板,称为jQuery Lightweight Plugin Boilerplate,几个月前我在另一个问题中引用了它。
最近,我开始使用 CoffeeScript 并查找了一个CoffeeScript jQuery 插件模板,我在这里找到了它。
这两者都实现了几乎相同的概念。这里的一些重要的不同之处是:
- 轻量级样板中不存在的私有对象
- CoffeeScript 模板中不同的命名空间块。(尽管我对Lightweight Boilerplate
methods[method].apply this, Array::slice.call(arguments, 1)
的命名空间块有所了解,但我完全不知道他做了什么。 - 在Lightweight Boilerplate中,对象的可链接性和迭代在命名空间块中得到处理,而在CoffeeScript 模板
method.init()
中也需return $(this)
要这样做$(this).each()
。
研究
所以我继续把这两个拼接起来。我写了自己的模板。它是这样的:
(($, window, document) ->
# ---------------------------------------------------------------------------
# Conventionally private variables
# ---------------------------------------------------------------------------
_PluginName = "FooBar"
_Defaults =
property: 'value' # etc. etc.
# ---------------------------------------------------------------------------
# Private methods
# ---------------------------------------------------------------------------
_Debug = (msg) ->
window.console.log(msg)
return
# ---------------------------------------------------------------------------
# Plugin Constructor
# ---------------------------------------------------------------------------
Plugin = (element, options) ->
@element = element
@options = $.extend true, {}, _Defaults, options
# TODO: Call methods to do stuff
return
# ---------------------------------------------------------------------------
# Plugin Methods
# ---------------------------------------------------------------------------
Plugin.prototype.init = () ->
# TODO: Plugin initializiation logic
return
Plugin.prototype.destroy = () ->
# TODO: Cleanup, unbind and eject
return
# ---------------------------------------------------------------------------
# Actual plugin body
# ---------------------------------------------------------------------------
$.fn[_PluginName] = (options) ->
return @.each () ->
($.data @, 'plugin_' + _PluginName
new Plugin @, options
) unless $.data @, 'plugin_' + _PluginName
return
) jQuery, window, document
我不是要求在两个插件之间进行比较。而且我的插件还不够完美。我从另一个问题的回答中发现,使用($, window, document)
闭包是一种矫枉过正。可能还有其他问题,欢迎大家指出并讨论。
尽管如此,我有一些非常具体的问题。
问题
这些传统上的“私有”对象/方法有多安全。如果有人故意打电话
Plugin()
而不是正确使用插件怎么办?可以_Defaults
在此闭包以外的任何范围内访问吗?这些“私有”对象的范围究竟是什么?它们是否会随意漂浮在 jQuery 命名空间中?他们能干涉任何事情吗?使用这些“私有”变量如何帮助使代码更好?
我不完全明白
prototype
。是init()
和本身destroy()
的属性Plugin()
吗?为什么要引用 as if 并在其自身的上下文中定义的属性......init()
如果我有一个定义为的对象怎么办?对象内部的功能是什么?destroy()
options
Plugin()
this.options
init()
destroy()
Plugin()
Plugin.prototype.methods
this
methods
注意:如果任何人都难以通过链接查看代码,请告诉我。我将编辑此问题以包含代码。我没有包括在内,因为那样问题会变得太长。