Prev: A practical exercise: fighting maskons
Next: FAQ Topic - How do I get a jsp/php variable into client-side javascript? (2009-11-10)
From: Asen Bozhilov on 9 Nov 2009 15:41 I read ajaxian.com. There i found one post which presented one new JavaScript framework. The name of the framework is call "Underscore". <URL: http://documentcloud.github.com/underscore/> | Underscore is a utility-belt library for JavaScript that provides | a lot of the functional programming support that you would | expect in Prototype.js (or Ruby), | but without extending any of the built-in JavaScript objects. It's the tie to go along with jQuery's tux. This is the first sentence in the page, that page must be documentation of framework. I don't like style like this. When you created framework, lived alone another framework. They have own problems and own advantages. However, if anybody want to see source code of "Underscore": <URL: http://documentcloud.github.com/underscore/underscore.js> The concern of the topic is identifiers name. What is the benefit from identifier like: _ $ I associated underscore with properties whos been "private". So i don't make documentation for properties who identifier name start with underscore. $ symbol in normal live i associated with USA dollar. In Ecma3: | 7.6 Identifiers | This standard specifies one departure from the grammar given in the Unicode standard: The dollar sign ($) and the | underscore (_) are permitted anywhere in an identifier. The dollar sign is intended for use only in mechanically | generated code. So using $ for identifier name from programmers will be means contradiction with ECMA3 documentation. I want signed identifiers, who means what exactly contains or doing. If i follow that fashion, soon i will be defined identifier like this one: var лев = "bg currency lev"; That is completely valid identifier, and its only two character much more from $.
From: David Mark on 9 Nov 2009 16:02 On Nov 9, 3:41 pm, Asen Bozhilov <asen.bozhi...(a)gmail.com> wrote: > I read ajaxian.com. There i found one post which presented one new > JavaScript framework. The name of the framework is call "Underscore". > <URL:http://documentcloud.github.com/underscore/> > > | Underscore is a utility-belt library for JavaScript that provides > | a lot of the functional programming support that you would > | expect in Prototype.js (or Ruby), > | but without extending any of the built-in JavaScript objects. It's > the tie to go along with jQuery's tux. None of that makes sense. For one, functional programming support is not what I would expect from Prototype. And jQuery is more of a clown suit than a tux. > > This is the first sentence in the page, that page must be > documentation of framework. I don't like style like this. When you > created framework, lived alone another framework. They have own > problems and own advantages. However, if anybody want to see source > code of "Underscore": > <URL:http://documentcloud.github.com/underscore/underscore.js> // Is a given array or object empty? _.isEmpty = function(obj) { return (_.isArray(obj) ? obj : _.values(obj)).length == 0; }; Searching a script for "isArray" is a little like searching for "mavigator.userAgent" (discard on discovery). > > The concern of the topic is identifiers name. What is the benefit from > identifier like: > _ > $ Zero, unless you've never heard of keyboard macros. Most of these scripts end up minified anyway (and/or compressed by the server, modems, etc.), so ridiculous variable names like this are of no practical value (in fact, it makes for illegible scripts). > > I associated underscore with properties whos been "private". So i > don't make documentation for properties who identifier name start with > underscore. Especially for a language without private members. ;) > $ symbol in normal live i associated with USA dollar. In Ecma3: As do most. > > | 7.6 Identifiers > | This standard specifies one departure from the grammar given in the > Unicode standard: The dollar sign ($) and the > | underscore (_) are permitted anywhere in an identifier. The dollar > sign is intended for use only in mechanically > | generated code. > > So using $ for identifier name from programmers will be means > contradiction with ECMA3 documentation. Yes, it is also seen as bad practice.
From: Peter Michaux on 9 Nov 2009 16:07 On Nov 9, 2:41 pm, Asen Bozhilov <asen.bozhi...(a)gmail.com> wrote: > I read ajaxian.com. There i found one post which presented one new > JavaScript framework. The name of the framework is call "Underscore". > <URL:http://documentcloud.github.com/underscore/> > > | Underscore is a utility-belt library for JavaScript that provides > | a lot of the functional programming support that you would > | expect in Prototype.js (or Ruby), > | but without extending any of the built-in JavaScript objects. It's > the tie to go along with jQuery's tux. > > This is the first sentence in the page, that page must be > documentation of framework. I don't like style like this. When you > created framework, lived alone another framework. They have own > problems and own advantages. However, if anybody want to see source > code of "Underscore": > <URL:http://documentcloud.github.com/underscore/underscore.js> > > The concern of the topic is identifiers name. What is the benefit from > identifier like: > _ > $ I think the benefit is they are short. Too short and cryptic, I think. > I associated underscore with properties whos been "private". So i > don't make documentation for properties who identifier name start with > underscore. > $ symbol in normal live i associated with USA dollar. In Ecma3: > > | 7.6 Identifiers > | This standard specifies one departure from the grammar given in the > Unicode standard: The dollar sign ($) and the > | underscore (_) are permitted anywhere in an identifier. The dollar > sign is intended for use only in mechanically > | generated code. > > So using $ for identifier name from programmers will be means > contradiction with ECMA3 documentation. The use of $ in an indentifier doesn't contradict ECMAScript 3 because $ was "intended for" not "reserved for". This issue has been discussed in c.l.js many times. I believe this statement is gone from the proposed ECMAScript 5 and if so I think it is good they removed it. Peter
From: David Mark on 9 Nov 2009 17:34 On Nov 9, 3:41 pm, Asen Bozhilov <asen.bozhi...(a)gmail.com> wrote: > I read ajaxian.com. There i found one post which presented one new > JavaScript framework. The name of the framework is call "Underscore". > <URL:http://documentcloud.github.com/underscore/> > > | Underscore is a utility-belt library for JavaScript that provides > | a lot of the functional programming support that you would > | expect in Prototype.js (or Ruby), > | but without extending any of the built-in JavaScript objects. It's > the tie to go along with jQuery's tux. > > This is the first sentence in the page, that page must be > documentation of framework. I don't like style like this. When you > created framework, lived alone another framework. They have own > problems and own advantages. However, if anybody want to see source > code of "Underscore": > <URL:http://documentcloud.github.com/underscore/underscore.js> > // Underscore.js // (c) 2009 Jeremy Ashkenas, DocumentCloud Inc. // Underscore is freely distributable under the terms of the MIT license. // Portions of Underscore are inspired by or borrowed from Prototype.js, // Oliver Steele's Functional, and John Resig's Micro-Templating. // For all details and documentation: // http://documentcloud.github.com/underscore/ Considering what follows, there seems to be at least one glaring omission. (function() { /*------------------------- Baseline setup ---------------------------------*/ // Establish the root object, "window" in the browser, or "global" on the server. var root = this; Oops, that is supposed to come first. :) // Save the previous value of the "_" variable. var previousUnderscore = root._; That's jQuery, so quite an eclectic mix. // If Underscore is called as a function, it returns a wrapped object that // can be used OO-style. This wrapper holds altered versions of all the // underscore functions. Wrapped objects may be chained. var wrapper = function(obj) { this._wrapped = obj; }; That too. // Create a safe reference to the Underscore object for reference below. var _ = root._ = function(obj) { return new wrapper(obj); }; A safe reference? // Export the Underscore object for CommonJS. if (typeof exports !== 'undefined') _ = exports; Waste of time. // Current version. _.VERSION = '0.4.2'; /*------------------------ Collection Functions: ---------------------------*/ // The cornerstone, an each implementation. // Handles objects implementing forEach, arrays, and raw objects. Where have I seen this before? _.each = function(obj, iterator, context) { var index = 0; try { if (obj.forEach) { obj.forEach(iterator, context); } else if (obj.length) { for (var i=0, l = obj.length; i<l; i++) iterator.call(context, obj[i], i, obj); } else { for (var key in obj) if (Object.prototype.hasOwnProperty.call (obj, key)) { iterator.call(context, obj[key], key, obj); } } } catch(e) { if (e != '__break__') throw e; } return obj; }; Well, not like _that_ anyway. :( /* ----------------------- Function Functions: -----------------------------*/ // Create a function bound to a given object (assigning 'this', and arguments, // optionally). Binding with arguments is also known as 'curry'. _.bind = function(func, context) { context = context || root; var args = _.toArray(arguments).slice(2); return function() { var a = args.concat(_.toArray(arguments)); return func.apply(context, a); }; }; // Bind all of an object's methods to that object. Useful for ensuring that // all callbacks defined on an object belong to it. _.bindAll = function() { var args = _.toArray(arguments); var context = args.pop(); _.each(args, function(methodName) { context[methodName] = _.bind(context[methodName], context); }); }; Bind by method name with an optional context. Deja vu. // Extend a given object with all of the properties in a source object. _.extend = function(destination, source) { for (var property in source) destination[property] = source [property]; return destination; }; // Create a (shallow-cloned) duplicate of an object. _.clone = function(obj) { if (_.isArray(obj)) return obj.slice(0); return _.extend({}, obj); }; Prototypian (i.e. backwards approach to inheritance). // Perform a deep comparison to check if two objects are equal. _.isEqual = function(a, b) { // Check object identity. if (a === b) return true; Waste of time. // Different types? var atype = typeof(a), btype = typeof(b); if (atype != btype) return false; // Basic equality test (watch out for coercions). if (a == b) return true; // One of them implements an isEqual()? if (a.isEqual) return a.isEqual(b); // If a is not an object by this point, we can't handle it. if (atype !== 'object') return false; Strict comparison is unneeded here. // Nothing else worked, deep compare the contents. Of course, typeof null == 'object' var aKeys = _.keys(a), bKeys = _.keys(b); So no wonder there is a try-catch in _each. // Different object sizes? if (aKeys.length != bKeys.length) return false; // Recursive comparison of contents. for (var key in a) if (!_.isEqual(a[key], b[key])) return false; That's not going to work at all for null (or very well for Object objects as the loop is unfiltered). return true; }; // Is a given array or object empty? _.isEmpty = function(obj) { return (_.isArray(obj) ? obj : _.values(obj)).length == 0; }; This is a bad design (differentiating between Object and Array objects). Perhaps the competent alternative was not "cool" enough. :) // Is a given value a DOM element? _.isElement = function(obj) { return !!(obj && obj.nodeType == 1); }; Even worse (trying to differentiate between host and Object objects). Cool though! // Is a given value a real Array? _.isArray = function(obj) { return Object.prototype.toString.call(obj) == '[object Array]'; }; Always an indication of a bad script. And this "Miller device" (quotes indicate the technique doesn't originate with that guy) is not 100% reliable (as discussed here repeatedly). // Is a given value a Function? _.isFunction = function(obj) { return Object.prototype.toString.call(obj) == '[object Function]'; }; Well, this one is just silly. Could use typeof for Function objects, of course, but I imagine this is aimed at developers who wish to design applications that must differentiate between host object methods and native functions. Why such designs would ever be considered is beyond me. // Is a given variable undefined? _.isUndefined = function(obj) { return typeof obj == 'undefined'; }; Didn't need that. /* -------------------------- Utility Functions: -------------------------- */ // Run Underscore.js in noConflict mode, returning the '_' variable to its // previous owner. Returns a reference to the Underscore object. _.noConflict = function() { root._ = previousUnderscore; return this; }; Stay off the jQuery. // Keep the identity function around for default iterators. _.identity = function(value) { return value; }; // Break out of the middle of an iteration. _.breakLoop = function() { throw "__break__"; }; OMG. // Generate a unique integer id (unique within the entire client session). // Useful for temporary DOM ids. var idCounter = 0; _.uniqueId = function(prefix) { var id = idCounter++; return prefix ? prefix + id : id; }; Yeah, that rings a bell. // Return a sorted list of the function names available in Underscore. _.functions = function() { var functions = []; for (var key in _) if (Object.prototype.hasOwnProperty.call(_, key)) Except in agents that do not support hasOwnProperty. functions.push(key); return _.without(functions, 'VERSION', 'prototype', 'noConflict').sort(); }; // JavaScript templating a-la ERB, pilfered from John Resig's // "Secrets of the JavaScript Ninja", page 83. Yikes. That's the one with the Samurai right? Written long before Resig had graduated from browser sniffing to object inferences. Not a good reference for writing a JS anything, let alone a GP library. _.template = function(str, data) { var fn = new Function('obj', 'var p=[],print=function(){p.push.apply(p,arguments);};' + 'with(obj){p.push(\'' + str .replace(/[\r\t\n]/g, " ") .split("<%").join("\t") .replace(/((^|%>)[^\t]*)'/g, "$1\r") .replace(/\t=(.*?)%>/g, "',$1,'") .split("\t").join("');") .split("%>").join("p.push('") .split("\r").join("\\'") + "');}return p.join('');"); return data ? fn(data) : fn; }; /*------------------------------- Aliases ----------------------------------*/ _.forEach = _.each; _.foldl = _.inject = _.reduce; _.foldr = _.reduceRight; _.filter = _.select; _.every = _.all; _.some = _.any; _.methods = _.functions; Why? /*------------------------ Setup the OOP Wrapper: --------------------------*/ // Helper function to continue chaining intermediate results. var result = function(obj, chain) { return chain ? _(obj).chain() : obj; }; // Add all of the Underscore functions to the wrapper object. _.each(_.functions(), function(name) { wrapper.prototype[name] = function() { Array.prototype.unshift.call(arguments, this._wrapped); return result(_[name].apply(_, arguments), this._chain); }; }); // Add all mutator Array functions to the wrapper. _.each(['pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift'], function(name) { wrapper.prototype[name] = function() { Array.prototype[name].apply(this._wrapped, arguments); return result(this._wrapped, this._chain); }; }); // Add all accessor Array functions to the wrapper. _.each(['concat', 'join', 'slice'], function(name) { wrapper.prototype[name] = function() { return result(Array.prototype[name].apply(this._wrapped, arguments), this._chain); }; }); // Start chaining a wrapped Underscore object. wrapper.prototype.chain = function() { this._chain = true; return this; }; // Extracts the result from a wrapped and chained object. wrapper.prototype.value = function() { return this._wrapped; }; })(); Definitely saw this ending coming. ;) All in all, a mishmash of ideas (most of the bad). I need a rubber stamp that reads "Avoid like the Plague".
From: "Michael Haufe ("TNO")" on 9 Nov 2009 17:37
On Nov 9, 2:41 pm, Asen Bozhilov <asen.bozhi...(a)gmail.com> wrote: > The concern of the topic is identifiers name. What is the benefit from > identifier like: > _ > $ It all stemmed from the desire to keep 3rd party code out of the global space. As a result, many major libraries have their own "namespace" where they keep their code. In the case of jQuery, and its fad with having the most terse syntax as possible, their "namespace" became the "$" symbol. The assumption was that no other library or code would have a global variable with that name, while at the same time being as short as possible. Since jQuery became popular (due to good and bad marketing), many wannabe libraries think a small global "namespace" like that is a good idea, so monkey see monkey do. This is my unqualified opinion though, so take it with a grain of salt. |