More Bootstrap.js simplifications.

This commit is contained in:
Jürg Lehni 2012-11-03 22:24:42 -07:00
parent 6ed1d67ada
commit a51f5af9c8

65
lib/bootstrap.js vendored
View file

@ -39,18 +39,16 @@ var Base = new function() { // Bootstrap scope
if (this.hasOwnProperty(i)) if (this.hasOwnProperty(i))
iter.call(bind, this[i], i, this); iter.call(bind, this[i], i, this);
}, },
_create = Object.create, // A ahort cut to a simplified version of Object.create that only
// supports the first parameter (in the emulation):
create = Object.create || function(proto) {
// From all browsers that do not offer Object.create(), we only
// support Firefox 3.5 & 3.5, but luckily this hack works there:
return { __proto__: proto };
},
_define = Object.defineProperty, _define = Object.defineProperty,
_describe = Object.getOwnPropertyDescriptor; _describe = Object.getOwnPropertyDescriptor;
function create(ctor) {
return _create
? _create(ctor.prototype)
// We only support Firefox 3.5 that does not offer Object.create,
// but luckily it supports this hack:
: { __proto__: ctor.prototype };
}
// Support a mixed environment of some ECMAScript 5 features present, // Support a mixed environment of some ECMAScript 5 features present,
// along with __defineGetter/Setter__ functions, as found in browsers today. // along with __defineGetter/Setter__ functions, as found in browsers today.
function define(obj, name, desc) { function define(obj, name, desc) {
@ -205,27 +203,6 @@ var Base = new function() { // Bootstrap scope
return dest; return dest;
} }
/**
* Private function that creates a constructor to extend the given object.
* When this constructor is called through new, a new object is craeted
* that inherits all from obj.
*/
function extend(obj) {
// Create the constructor for the new prototype that calls initialize
// if it is defined.
var ctor = function() {
// Call the constructor function, if defined
if (this.initialize)
return this.initialize.apply(this, arguments);
};
ctor.prototype = obj;
// Add a toString function that delegates to initialize if possible
ctor.toString = function() {
return (this.prototype.initialize || function() {}).toString();
};
return ctor;
}
/** /**
* Converts the argument to an iterator function. If none is specified, the * Converts the argument to an iterator function. If none is specified, the
* identity function is returned. * identity function is returned.
@ -287,11 +264,19 @@ var Base = new function() { // Bootstrap scope
}, },
extend: function(src/* , ... */) { extend: function(src/* , ... */) {
var proto = create(this), var ctor = function() {
ctor = extend(proto); // Call the constructor function, if defined
if (this.initialize)
return this.initialize.apply(this, arguments);
};
ctor.prototype = create(this.prototype);
// Add a toString function that delegates to initialize if possible
ctor.toString = function() {
return (this.prototype.initialize || function() {}).toString();
};
// The new prototype extends the constructor on which extend is // The new prototype extends the constructor on which extend is
// called. Fix constructor. // called. Fix constructor.
define(proto, 'constructor', define(ctor.prototype, 'constructor',
{ value: ctor, writable: true, configurable: true }); { value: ctor, writable: true, configurable: true });
// Copy over static fields, as prototype-like inheritance // Copy over static fields, as prototype-like inheritance
// is not possible for static fields. Mark them as enumerable // is not possible for static fields. Mark them as enumerable
@ -332,13 +317,7 @@ var Base = new function() { // Bootstrap scope
* of Function.prototype.extend. * of Function.prototype.extend.
*/ */
extend: function(/* src, ... */) { extend: function(/* src, ... */) {
// Notice the "new" here: the private extend returns a constructor var res = create(this);
// as it's used for Function.prototype.extend as well. But when
// extending objects, we want to return a new object that inherits
// from "this". In that case, the constructor is never used again,
// its just created to create a new object with the proper
// inheritance set and is garbage collected right after.
var res = new (extend(this));
return res.inject.apply(res, arguments); return res.inject.apply(res, arguments);
}, },
@ -358,7 +337,11 @@ var Base = new function() { // Bootstrap scope
// Expose some local privates as Base generics. // Expose some local privates as Base generics.
each: each, each: each,
clone: clone, clone: clone,
create: create, // Base.create does something different from Object.create, it only
// works on constructors and uses their prototype.
create: function(ctor) {
return create(ctor.prototype);
},
define: define, define: define,
describe: describe, describe: describe,
iterator: iterator, iterator: iterator,