问题
I was looking over the JavaScript source code for SlickGrid.
I've noticed that slick.grid.js has the following structure:
(function($) {
// Slick.Grid
$.extend(true, window, {
Slick: {
Grid: SlickGrid
}
});
var scrollbarDimensions; // shared across all grids on this page
////////////////////////////////////////////////////////////////////////////
// SlickGrid class implementation (available as Slick.Grid)
/**
* @param {Node} container Container node to create the grid in.
* @param {Array,Object} data An array of objects for databinding.
* @param {Array} columns An array of column definitions.
* @param {Object} options Grid options.
**/
function SlickGrid(container,data,columns,options) {
/// <summary>
/// Create and manage virtual grid in the specified $container,
/// connecting it to the specified data source. Data is presented
/// as a grid with the specified columns and data.length rows.
/// Options alter behaviour of the grid.
/// </summary>
// settings
var defaults = {
...
};
...
// private
var $container;
...
////////////////////////////////////////////////////////////////////////
// Initialization
function init() {
/// <summary>
/// Initialize 'this' (self) instance of a SlickGrid.
/// This function is called by the constructor.
/// </summary>
$container = $(container);
...
}
////////////////////////////////////////////////////////////////////////
// Private & Public Functions, Getters/Setters, Interactivity, etc.
function measureScrollbar() {
...
}
////////////////////////////////////////////////////////////////////////
// Public API
$.extend(this, {
"slickGridVersion": "2.0a1",
// Events
"onScroll": new Slick.Event(),
...
// Methods
"registerPlugin": registerPlugin,
...
});
init();
}
}(jQuery));
Some code has been omitted for brevity and clarity, but this should give you the general idea.
What is the purpose of the the following:
(function($) { // code }(jQuery));
Is this the module pattern that I've seen talked about? Is this meant to keep the global namespace clean?What do the
$.extend()
lines mean?: The top$.extend(true, window, { // code });
looks like it has to do with a "namespace"; what's a namespace? It looks like the bottom$.extend(this, { // code });
is used to exposed 'public' members and functions? How would you define a private function or variable?How would you initialize multiple "SlickGrids" if you wanted to? How much would they share and how would they interact? Note the "constructor" function:
function SlickGrid(...) { // code }
.What are some books, links, and other resources on coding in this style? Who invented it?
Thanks! ♥
回答1:
This is a jQuery plugin.
(function($) { // code }(jQuery));
gives you a new function scope so your names are not dumped into the global scope. Passing jQuery as $ lets you use the $ shorthand even if other Javascript libraries use $.
$.extend
is a jQuery method to copy properties from one object to another. The first argument true
means it should be a deep rather than a shallow copy. By extending window
, new global properties are created, in this case, Slick
.
The $.extend(this,...)
at the bottom is in a capitalized function SlickGrid. SlickGrid
is meant to be used as a constructor, in which case this
will be the newly-created object, so this extend
is adding properties to the object. They are effectively public members. In this code sample, measureScrollbar
is private: it is only visible to the code defined in this function, not outside it.
You can create a number of grids with:
var grid1 = new Slick.Grid(blah, blah);
var grid2 = new Slick.Grid(blah, blah);
In the code you've shown, the only thing these two instances will share is the scrollBarDimensions
variable.
回答2:
(function($) { // code }(jQuery))
This is a closure. It basically keeps everything inside it "// code" safe from things outside it. You pass in jQuery and the $, but someone with more knowledge will have to explain why that is necessary.
$.extend()
This is a jQuery function that will take two objects and merge them together. Replacing the first object "window" with the second object {Slick: {Grid: SlickGrid}}. This means if there is a window object with Grid:Null it would now equal Grid:SlickGrid.
Adding true as a first parameter means it will replace nested objects as well:
var firstObj = { myObj:{
first:this,
second: {
new: obj
}
}}
$.extend(true, firstObj, {myObj:{second:{new:newer}}});
This is useful if you are using a lot of objects to store information.
Not sure what you mean by #3, but look at http://960.gs for a good grid system.
JavaScript the Good Parts is a great book. Pro JavaScript by John Resig is also a good book to take you beyond the basics.
回答3:
Simply put, guy in your example just wrote jQuery plug-in of sorts... Check PLUGINS section of jquery.com for more references to sources on how to code plugins. They are simple, straightforward and fun to explore.
回答4:
For the first question, this construct is a way to allow jQuery to coexist with other libraries which may use the $ function, but still use $ to reference jQuery within a code block.
The entire package is wrapped in a function call with $
as a parameter. The only "main" activity when this is run is to call that function with jQuery
as an argument, this giving a reference to the well-known global jQuery
to the local parameter $
, which masks any global value that $
may have.
回答5:
1) That function is invoked immediately when the JS file is loaded. It receives the jquery instance as parameter and makes it available internally as "$". All code is encapsulated in that function so (unless you forget a var in front a yet undeclared variable) nothing pollutes the global namespace.
2) All properties of the 2nd object are copied to the 1st object, here "window", which also is the global namespace object in a web browser. Therefore this code does not make much sense. It pretends to encapsulate but does the opposite. Neither does the second invocation of $.extend make all that much sense. It's not wrong, I just think the code "pretends".
4) I very highly recommend you check out the videos from Douglas Crockford at http://developer.yahoo.com/yui/theater/ Crockford is a JS god, very famous (among serious JS programmers) - and in addition great fun to listen to :)
来源:https://stackoverflow.com/questions/5145092/what-is-this-design-pattern-known-as-in-javascript-jquery