Core

Core.js represents the first file in the library on which all others depend. Here are the docs for Core.js

MooTools

MooTools has a namespace which contains a version number. This namespace isn't used for much else, but it's useful if you need to query the page to see what version of MooTools is in the environment:

var MooTools = {
	'version': 1.2
};

$chk

$chk returns true if the passed in value/object exists (is not undefined or null) or is 0, otherwise returns false. Note that $chk will return false for empty strings (but not for empty arrays or objects).

$chk([]); //true
execute this code
$chk(0); //true
execute this code
$chk(''); //false
execute this code
$chk(null); //false
execute this code
$chk(false); //false
execute this code

It's similar to $defined but, unlike defined which ONLY checks for undefined and null, $chk actually evaluates the property unless it is zero (in which case it returns true).

$defined(''); //true
execute this code
$defined(false); //true
execute this code

$clear

$clear clears the passed in timeout:

var oneSec = setTimeout(function(){alert('one second later...')}, 1000);
$clear(oneSec); //nevermind
execute this code

$defined

$defined quite simply returns true if the argument passed to it is not undefined or null:

var x = null;
console.log($defined(x)); /*	false	*/
function example(value){
	console.log($defined(value));
}
example(); /*	logs false; no argument passed	*/
execute this code

$each

If you want to iterate through an iterable object (such as the arguments passed to a function) without applying all the array properties to it (which is slightly slower), you can use $each() to do this.

$each(["one", "two", "three"],function(number){
  alert(number);
}); //alert one, two, three
execute this code

$each also lets you iterate over objects:

$each({apple:'red',lemon:'yellow',lime:'green'}, function(value, key){
	console.log(key+"s are "+value);
});
//logs apples are red, lemons are yellow, limes are green
execute this code

Like Array.each, it can take a third argument for binding.

$empty

Sometimes you need a placeholder for functions that will be defined later. This is useful for callback functions that you need to define and execute later. By using an empty function that does nothing, you don't have to worry if the member has been defined before it's executed. This will make more sense when you start using the Events and Options classes. Anyway, $empty is just that - an empty function.

$lambda

This is a somewhat abstract shortcut. $lambda creates a function that returns the argument you pass it. So, if you pass it a string, you'll get back a function that returns that string. If you pass it a function, it just returns that function to you.

$lambda is useful when you're writing classes and interfaces that you intend others to use and you want to accept a function or a value. It's also useful when you have a value and you just need a function to return it that you can then pass to something else. This is perhaps best explained with an example:

$('myLink').addEvent('click', function(){
	return false; //stop the browser from following the link
});
//versus:
$('myLink').addEvent('click', $lambda(false)); //SAME THING!

Again, it's just a shortcut for creating a function that returns the specified value.

$merge and $extend

One of the basic concepts in MooTools is reusability. The ability to inherit properties from one object to another or merge the properties of two objects is at the heart of what MooTools does. $merge and $extend both allow you to combine the properties of two javascript objects offering up numerous opportunities for clean and reusable code.

These two code blocks do the same thing EXCEPT that $merge does not alter any of the items passed to it (returning the result instead) while $extend changes the first argument to now include the values of the second.

var fruits = {
	apple: 'red',
	lemon: 'yellow'
};
var otherFruits = {
	apple: 'green',
	grape: 'purple'	
};
$extend(fruits, otherFruits); 
/*	fruits has been altered by $extend	*/
console.log(fruits);
/*	logs: {apple:'green', lemon: 'yellow', grape: 'purple'}	*/
execute this code

In the example above we see the two objects merged, and because otherFruits was passed in later than fruits its values trumped those found in the fruits object (so apple came out "green" instead of "red"). Here is $merge doing the same thing, but note that fruits is unaltered and to receive the result of the operation we must store it in a variable using equals =.

var fruits = {
	apple: 'red',
	lemon: 'yellow'
};
var otherFruits = {
	apple: 'green',
	grape: 'purple'	
};
var newFruits = $merge(fruits, otherFruits); 
console.log('newFruits: ', newFruits);
/*	fruits has NOT been altered by $merge	*/
console.log('unaltered fruits: ', fruits);
/*	logs: {apple:'red', lemon: 'yellow'}	*/
 
fruits = $merge(fruits, otherFruits); 
/*	fruits HAS been altered by setting the result using =	*/
console.log('fruits altered: ', fruits);
/*	logs: {apple:'green', lemon: 'yellow', grape: 'purple'}	*/
execute this code

Note: that $extend, like $merge, returns the result of the operation, but remember it also alters the first argument.

//continued from above
var newFruits = $extend(fruits, otherFruits);
//newFruits == fruits; they are the same object

Comparing $merge and $extend

Unlike $extend, $merge can take any number of arguments with each argument's existing properties trumping the next.

var fruits = {
	apple: 'red',
	lemon: 'yellow'
};
var otherFruits = {
	apple: 'green',
	grape: 'purple'	
};
var yetMoreFruits = {
	apple: 'yellow',
	orange: 'orange'
};
var newFruits = $merge(fruits, otherFruits, yetMoreFruits);
console.dir(newFruits);
/*	logs: {apple:'yellow', lemon: 'yellow', grape: 'purple', orange: 'orange'}	*/
execute this code

The value of apple in yetMoreFruits is preserved because it was the last passed in.

$merge recurses

It's important to note that $merge is recursive. Unlike $extend, which just takes the members of the second argument and adds them to the first argument, $merge will do the same except when one of the members is another object. In this case it will recurse into that object and copy its values into the result.

This is important, because in javascript if you ever type var object = someOtherObject you are not creating a copy of that object but merely another pointer to it:

var x = {one: 1};
var y = x;
console.log(x == y); /*	true	*/
 
x.two = 2; /*	changing x also changes y	*/
console.log(y.two); /*	2	*/
execute this code

But two objects with the same properties are NOT == to each other:

var x = {one: 1};
var y = {one: 1};
console.log(x == y); /*	false	*/
 
x.two = 2; /*	changing x does not change y	*/
console.log(y.two); /*	undefined	*/
execute this code

If you use $extend to merge two objects together and the second object contains members that are also objects, you will create a link between the two:

var fruits = {
	apple: 'red',
	lemon: 'yellow'
};
var detailedFruits = {
	apple: {
		goldenDelicious: 'yellow',
		pinkLady: 'red',
		sour:'green'
	}
};
$extend(fruits, detailedFruits);
console.dir(fruits);
/*	logs {apple:{goldenDelicious:'yellow', pinkLady:'red', sour: 'green'}, lemon: 'yellow'}	*/
 
/*	changing apple in one changes it in both	*/
detailedFruits.apple.pinkLady = 'pink';
console.dir(fruits);
/*	logs {apple:{goldenDelicious:'yellow', pinkLady:'pink', sour: 'green'}, lemon: 'yellow'}	*/
execute this code

The link between fruits and detailedFruits shouldn't exist, but it does because apple is an object.

$merge, though, will recurse into detailedFruits.apple copying the values of each of its members so that this link does not exist.

var fruits = {
	apple: 'red',
	lemon: 'yellow'
};
var detailedFruits = {
	apple: {
		goldenDelicious: 'yellow',
		pinkLady: 'red',
		sour:'green'
	}
};
fruits = $merge(fruits, detailedFruits);
console.dir(fruits);
/*	logs {apple:{goldenDelicious:'yellow', pinkLady:'red', sour: 'green'}, lemon: 'yellow'}	*/
 
/*	now changes to one object do not affect the other	*/
detailedFruits.apple.pinkLady = 'pink';
console.dir(fruits);
/*	logs {apple:{goldenDelicious:'yellow', pinkLady:'red', sour: 'green'}, lemon: 'yellow'}	*/
execute this code

Most of the time you won't use $merge. It's used within MooTools for certain types of inheritance and whenever you need to combine objects that contain objects, but it's far less efficient than $extend. If you understand the purpose of each and use them appropriately you shouldn't have any trouble.

$pick

$pick returns the first object if defined (it uses $defined), otherwise returns the second.

Pick is just a shortcut for an if/else statement. It takes any number of variables and returns the first one that is defined or not null. This means you can call $pick(false, defaultVal) and $pick will return false, because it's defined.

function test(variable){
	alert($pick(variable, 'no variable defined!'));
}
 
test(); /*	alerts 'no variable defined!'	*/
test('hi'); /*	alerts 'hi'	*/
test(false); /*	alerts 'false'	*/
test(''); /*	alerts ''	*/
execute this code

If you were to write this function above out without $pick, it'd look like this:

function test(variable){
	if(typeof variable == "undefined" || variable == null) alert('no variable defined');
	else alert(variable);
}

What's important to note here is that zero, an empty string, and false when passed to $pick will return that value. If you were to evaluate the variable itself: if(variable) alert(variable) - your conditional would evaluate those values (zero, "", the boolean false) and alert that no variable was defined.

It saves you the time of writing out a long if statement. But it gets even more useful when you need to evaluate numerous things:

function test(variable) {
	variable = $pick(variable, someOtherVariable, defaultValue);
}
//typing this out with if/else statements would look like:
function test(variable){
	if(typeof variable == "undefined" || variable == null){
		if(typeof someOtherValue != "undefined" && someOtherValue != null) 
			variable = someOtherValue;
		else
			variable = defaultValue;
	}
	return variable;
}

$random

Returns a random number between the minimum and maximum you pass in:

$random(0,9); //returns a random number between 0 and 9
execute this code

$splat

$splat converts the argument you pass it into an array if it isn't already an array. This is useful when you want to have a method that accept an argument that is either a single object or an array of them.

function myFavoriteThings(things){
	alert("I like " + $splat(things).join(" and "));
};
myFavoriteThings("cookies"); /*I like cookies*/
myFavoriteThings(["cookies", "cake", "ice cream"]); 
/*I like cookies and cake and ice cream*/
execute this code

$time

A shortcut for new Date.getTime();.

$time(); //the current time value
execute this code

$try

$try will attempt to execute a number of methods and returns the value of the first function that doesn't throw an error.

$try(function(){
	console.log(foo.bar); /*this doesn't exist, throws an error*/
}, function(){
	var msg = null;
	console.log(msg.length); /*null has no properties, throws an error*/
}, function(){
	console.log("I don't contain any errors");
});
execute this code

$type

Javascript is a loosely typed language and this often causes a lot of grief for those that work with it. MooTools' $type function helps by letting you figure out what something is. $type returns the type of an object ('function' or 'string', etc.) or false if the object is not defined:

  • 'element' if obj is a DOM element node
  • 'textnode' if obj is a DOM text node
  • 'whitespace' if obj is a DOM whitespace node
  • 'arguments' if obj is an arguments object
  • 'object' if obj is an object
  • 'array' if obj is an array
  • 'string' if obj is a string
  • 'number' if obj is a number
  • 'date' if obj is a date
  • 'boolean' if obj is a boolean
  • 'function' if obj is a function
  • 'regexp' if obj is a regular expression
  • 'class' if obj is a Class. (created with new Class, or the extend of another class)
  • 'collection' if obj is a native htmlelements collection, such as childNodes, getElementsByTagName .. etc.
  • 'window' if obj is the window object
  • 'document' if obj is the document object
  • false (boolean) if the object is not defined or none of the above

This example uses the $() function; see Native>Element>$().

$type($('typeTest'))//element if $('typeTest') exists, 
//otherwise boolean, because $() returns false if the element isn't found.
//this example returns true
execute this code
$type($('elementNotPresent'));
//returns false, because $() returns null here
execute this code

<div id="typeElement" style="display: none">
this is a text node
<span> </span>
</div>
console.log($type($('typeElement').childNodes[0]));// "textnode"
console.log($type($('typeElement').getElement('span').childNodes[0]));// "whitespace"
execute this code
function test(){
	console.log($type(arguments));
}
test('one','two'); /*	logs "arguments"	*/
test(); /*	also logs "arguments"	*/
execute this code
$type({});//"object"
execute this code
$type('hi'); //"string"
execute this code
$type(''); //"string"
execute this code
$type(0); // "number"
execute this code
$type(true); // "boolean"
execute this code
$type(false); // "boolean"
execute this code
$type(function(){});//"function"
execute this code
$type([]);//"array"
execute this code
$type(new Class());// "class"
execute this code
$type(document.getElementsByTagName('p'));// "collection"
execute this code
$type(/([.*])/); //"regexp"
execute this code
var x = null;
$type(x);// false
execute this code
$type(); // false
execute this code

mootorial/01-core.txt · Last modified: 2011/04/20 01:30 by jcdufourd