P
petermichaux
From Flanagan's JavaScript: The Definitive Guide 5th edition.
1.1.2 JavaScript is Not Simple
Programmers who attempt to use JavaScript for nontrivial tasks
often find the process frustrating if they do not have a solid
understanding of the language.
1.2 Versions of JavaScript
Any browsers newer than Netscape 4.5 or Internet Explorer 4
supports
the latest version of the language. As a practical matter, you are
unlikely to encounter a noncompliant interpreter.
8.1.3 Naming Functions
The client-side JavaScript framework Prototype
(http://prototype.conio.net), elegantly uses the function $()
(yes, just a dollar sign) as an intelligent replacement
for the very common but hard-to-type document.getElementById().
9.2.2 Extending Built-in Types
There is a strong argument against extending built-in types with
your
own methods; if you do so, you are essentially creating your own
custom
version of the core JavaScript API. Any other programmers who have
to
read or maintain your code will likely find it confusing if your
code
includes methods they have never heard of. Unless you are creating
a low-level JavaScript framework that you expect to be adopted by
many
other programmers, it is probably best to stay away from prototype
objects
of the built in types.
Note that you must _never_ add properties to Object.prototype. Any
properties or methods you add are enumerable with a for/in loop,
and
adding them to Object.prototype makes them visible in every single
JavaScript object. An empty object, {}, is expected to have no
enumerable
properties. Anything added to Object.prototype becomes an
enumerable
property of the empty object and will likely break code that uses
objects as associative arrays.
9.6 Extending Without Inheriting
function borrowMethods(borrowFrom, addTo) {
var from = borrowFrom.prototype // prototype object to borrow
from
var to = addTo.prototype // prototype object to extend
for(m in from) {
if (typeof from[m] != "function") continue; // ignore
nonfunctions
to[m] = from[m]; //borrow the method
}
}
9.7.3 Duck Typing
Example 9-8 Testing whether an object provides methods
// Return true if o has methods with the same name and arity as all
// methods in c.prototype. Otherwise, return false. Throws and
exception
// if c is a built in type with nonenumerable methods.
function provides(o, c) {
9.8 Example: A defineClass() Utility Method
* After the prototype object is fully initialized, this function
* verifies that the prototype includes methods whose names and
* number of arguments match the instance methods defined by each
* of these classes. No methods are copied; this is simply an
* assertion that this class "provides" the functionality of the
* specified classes.
10.1 Creating Modules and Namespaces
In this code, the global flanagan object is a namespace for
namespaces.
10.2 Importing Symbols from Namespaces
After loading the com.davidflanagan.Class module, for example, a
user
of that module might write the following:
// This is an easier name, to save typing.
var define = com.davidflanagan.Class.define
It is the module developers responsibility to use namespaces to
prevent
collisions. But it is the module user's prerogative to import
symbols from
the module's namespace into the global namespace.
1.1.2 JavaScript is Not Simple
Programmers who attempt to use JavaScript for nontrivial tasks
often find the process frustrating if they do not have a solid
understanding of the language.
1.2 Versions of JavaScript
Any browsers newer than Netscape 4.5 or Internet Explorer 4
supports
the latest version of the language. As a practical matter, you are
unlikely to encounter a noncompliant interpreter.
8.1.3 Naming Functions
The client-side JavaScript framework Prototype
(http://prototype.conio.net), elegantly uses the function $()
(yes, just a dollar sign) as an intelligent replacement
for the very common but hard-to-type document.getElementById().
9.2.2 Extending Built-in Types
There is a strong argument against extending built-in types with
your
own methods; if you do so, you are essentially creating your own
custom
version of the core JavaScript API. Any other programmers who have
to
read or maintain your code will likely find it confusing if your
code
includes methods they have never heard of. Unless you are creating
a low-level JavaScript framework that you expect to be adopted by
many
other programmers, it is probably best to stay away from prototype
objects
of the built in types.
Note that you must _never_ add properties to Object.prototype. Any
properties or methods you add are enumerable with a for/in loop,
and
adding them to Object.prototype makes them visible in every single
JavaScript object. An empty object, {}, is expected to have no
enumerable
properties. Anything added to Object.prototype becomes an
enumerable
property of the empty object and will likely break code that uses
objects as associative arrays.
9.6 Extending Without Inheriting
function borrowMethods(borrowFrom, addTo) {
var from = borrowFrom.prototype // prototype object to borrow
from
var to = addTo.prototype // prototype object to extend
for(m in from) {
if (typeof from[m] != "function") continue; // ignore
nonfunctions
to[m] = from[m]; //borrow the method
}
}
9.7.3 Duck Typing
Example 9-8 Testing whether an object provides methods
// Return true if o has methods with the same name and arity as all
// methods in c.prototype. Otherwise, return false. Throws and
exception
// if c is a built in type with nonenumerable methods.
function provides(o, c) {
9.8 Example: A defineClass() Utility Method
* After the prototype object is fully initialized, this function
* verifies that the prototype includes methods whose names and
* number of arguments match the instance methods defined by each
* of these classes. No methods are copied; this is simply an
* assertion that this class "provides" the functionality of the
* specified classes.
10.1 Creating Modules and Namespaces
In this code, the global flanagan object is a namespace for
namespaces.
10.2 Importing Symbols from Namespaces
After loading the com.davidflanagan.Class module, for example, a
user
of that module might write the following:
// This is an easier name, to save typing.
var define = com.davidflanagan.Class.define
It is the module developers responsibility to use namespaces to
prevent
collisions. But it is the module user's prerogative to import
symbols from
the module's namespace into the global namespace.