console.log(Math);//show at Console in browserassert(true, "message");
log(variable);//show value of varassert( true, "I'll pass." ); //passassert( "truey", "So will I." ); //passassert( false, "I'll fail." ); //falseassert( null, "So will I." ); //falselog( "Just a simple log", "of", "values.", true ); //LOG Just a simple log of values. true
error( "I'm an error!" ); //error
Defining Function
var canFly = function() {returntrue; };
window.isDeadly = function() {returntrue; };
log(isNimble, canFly, isDeadly);//LOG function isNimble(){ return true; } function (){ return true; } function (){ return true; }//方法定义要在使用之前
assert( typeof canFly == "undefined", "canFly doesn't get that benefit." ); //PASS canFly doesn't get that benefit.
assert( typeof isDeadly == "undefined", "Nor does isDeadly." ); //PASS Nor does isDeadly.var canFly = function() {returntrue; };
window.isDeadly = function() {returntrue; };
//方法定义在return之后functionstealthCheck() {
log(stealth());
return stealth();
functionstealth() {return"below return"; }
}
stealthCheck();
Named Functions
functionyell(n) {return n > 0 ? yell(n - 1) + "a" : "hiy";
}
log(yell(4)); // "hiyaaaa"//myNinja是内部方法名称,外部无效var ninja = functionmyNinja() {
assert(ninja == myNinja, "This function is named two things - at once!");
};
ninja();//PASS This function is named two things - at once!
assert(typeof myNinja == "undefined", "But myNinja isn't defined outside of the function.");//PASS But myNinja isn't defined outside of the function.
log(ninja);//LOG function myNinja(){ assert( ninja == myNinja, "This function is named two things - at once!" ); }//对象属性声明为方法var ninja = {
yell: function(n) {return n > 0 ? ninja.yell(n - 1) + "a" : "hiy";
}
};
log( ninja.yell(4)); // "hiyaaaa"//方法引用时要给匿名方法一个名称,不然方法实际指向原方法,删除原方法会报错var ninja = {
yell: functionyell(n) {return n > 0 ? yell(n - 1) + "a" : "hiy";
}
};
log( ninja.yell(4)); // "hiyaaaa"var samurai = { yell: ninja.yell };
var ninja = null;
log( samurai.yell(4));//"hiyaaaa"//arguments.callee is the function itselfvar ninja = {
yell: function(n) {return n > 0 ? arguments.callee(n - 1) + "a" : "hiy";
}
};
log( ninja.yell(4));// "hiyaaaa"
Functions as Objects
var obj = {};
var fn = function() { };
obj.prop = "some value";
fn.prop = "some value";
assert( obj.prop == fn.prop, "Both are objects, both have the property." );//pass//缓存方法结果functionisPrime(num) {var prime = num != 1; // Everything but 1 can be primefor (var i = 2; i < num; i++) {
if (num % i == 0) {
prime = false;
break;
}
}
isPrime.cache = prime;
return prime;
}
isPrime.cache;
assert(isPrime(5), "Make sure the function works, 5 is prime.");
log(isPrime.cache);
Context
functionkatana() {this.isSharp = true;
}
katana();
log(isSharp === true);// true "A global object now exists with that name and value." );var shuriken = {
toss: function() {this.isSharp = true;
}
};
shuriken.toss();
log(shuriken.isSharp === true);// true "When it's an object property, the value is set within the object." );//call/apply会指向具体的上下文,局部变量var object = {};
functionfn() {returnthis;
}
assert( fn() == this, "The context is the global object." );
assert( fn.call(object) == object, "The context is changed to a specific object." );
// call() takes any function arguments separately.// apply() takes any function arguments as an arrayMath.max(1, 2, 3);
Math.max.apply(null, [1, 2, 3]);
Math.max.call(null, 1, 2, 3);
//loop循环实现functionloop(array, fn) {for (var i = 0; i < array.length; i++)
fn.call(array, array[i], i);
}
var num = 0;
loop([0, 1, 2], function(value, i) {
assert(value == num++, "Make sure the contents are as we expect it.");
assert(thisinstanceofArray, "The context should be the full array.");
});
Instantiation
functionNinja() {this.name = "Ninja";
}
var ninjaA = Ninja();
assert( !ninjaA, "Is undefined, not an instance of Ninja." );
var ninjaB = new Ninja();
assert( ninjaB.name == "Ninja", "Property exists on the ninja instance." );
//this指向新创建的对象functionNinja() {this.swung = false;
// Should return truethis.swingSword = function() {this.swung = !this.swung;
returnthis.swung;
};
}
var ninja = new Ninja();
assert(ninja.swingSword(), "Calling the instance method.");
assert(ninja.swung, "The ninja has swung the sword.");
var ninjaB = new Ninja();
assert(!ninjaB.swung, "Make sure that the ninja has not swung his sword.");
//set namefunctionNinja(name) {// Implement!this.changeName = functionchangeName(name2) {returnthis.name = name2;
}
returnthis.changeName(name);
}
var ninja = new Ninja("John");
assert(ninja.name == "John", "The name has been set on initialization");
ninja.changeName("Bob");
assert(ninja.name == "Bob", "The name was successfully changed.");
//function对new关键字的替换实现functionUser(first, last) {if ( !(thisinstanceofarguments.callee) )
returnnew User(first, last);
this.name = first + " " + last;
}
var name = "Resig";
var user = User("John", name);
assert( user, "This was defined correctly, even if it was by mistake." );
assert( name == "Resig", "The right name was maintained." );
Flexible Arguments
functionmultiMax(multi) {// Make an array of all but the first argument var allButFirst = Array().slice.call( arguments, 1 );
// Find the largest number in that array of arguments var largestAllButFirst = Math.max.apply( Math, allButFirst );
// Return the multiplied result return multi * largestAllButFirst;
}
assert( multiMax(3, 1, 2, 3) == 9, "3*3=9 (First arg, by largest.)" );
Closures 闭包作用域, 隐藏函数内部状态
functionaddNum(myNum) {return num + myNum;
}
num = 15;
assert(addNum(5) == 20, "Add two numbers together, one from a closure.");
//used with event listenersvar count = 1;
var elem = document.createElement("li");
elem.innerHTML = "Click me!";
elem.onclick = function() {
log( "Click #", count++ );
};
document.getElementById("results").appendChild( elem );
assert( elem.parentNode, "Clickable element appended." );
//variable valuevar a = 5;
functionrunMe(a) {
assert(a == 6, "Check the value of a.");
functioninnerRun() {
assert(b == 7, "Check the value of b.");
assert(c == undefined, "Check the value of c.");
}
var b = 7;
innerRun();
var c = 8;
}
runMe(6);
for (var d = 0; d < 2; d++) {
setTimeout(function() {
assert(d == d, "Check the value of d.");
}, 100);
}
Temporary Scope
var myLib = (function() {functionmyLib() {// Initialize
}
// ... return myLib;
})();
var count = 0;
for (var i = 0; i < 4; i++) (function(a) {
setTimeout(function() {
assert(a == count++, "Check the value of i.");
log(a);//0,1,2,3
}, i * 200);
})(i);
Function Prototypes
functionNinja() {this.swingSword = function() {return"true";
};
}
// Should return false, but will be overridden
Ninja.prototype.swingSword = function() {return"false";
};
var ninja = new Ninja();
log(ninja.swingSword());//true//原型方法会影响所有相同构造函数的对象functionNinja() {this.swung = "this is swung";
}
var ninjaA = new Ninja();
var ninjaB = new Ninja();
Ninja.prototype.swingSword = function() {returnthis.swung;
};
log(ninjaA.swingSword());
//方法链必须返回this functionNinja() {this.swung = true;
}
var ninjaA = new Ninja();
Ninja.prototype.swing = function() {this.swung = false;
returnthis;
};
log(ninjaA.swing().swung)//false
Instance Type
var ninja = new Ninja();
assert( typeof ninja == "object", "However the type of the instance is still an object." );
assert( ninja instanceof Ninja, "The object was instantiated properly." );
assert( ninja.constructor == Ninja, "The ninja object was created by the Ninja function." );
//constructor() 函数var ninja = (function() {functionNinja() { }
returnnew Ninja();
})();
// Make another instance of Ninja var ninjaB = new ninja.constructor();
assert( ninja.constructor == ninjaB.constructor, "The ninjas come from the same source." );
Inheritance
functionPerson() { }
Person.prototype.dance = function() { };
functionNinja() { }
// Achieve similar, but non-inheritable, results
Ninja.prototype = Person.prototype;
Ninja.prototype = { dance: Person.prototype.dance };
assert((new Ninja()) instanceof Person, "Will fail with bad prototype chain.");//fail// Only this maintains the prototype chain
Ninja.prototype = new Person();
var ninja = new Ninja();
assert(ninja instanceof Ninja, "ninja receives functionality from the Ninja prototype");
assert(ninja instanceof Person, "... and the Person prototype");
assert(ninja instanceofObject, "... and the Object prototype");
Built-in Prototypes
if (!Array.prototype.forEach) {
Array.prototype.forEach = function(fn) {for (var i = 0; i < this.length; i++)
fn(this[i], i, this);
};
}
["a", "b", "c"].forEach(function(value, index, array) {
assert(value, "Is in position " + index + " out of " + (array.length - 1));
});
//keysObject.prototype.keys = function() {var keys = [];
for (var i inthis)
keys.push(i);
return keys;
}
var obj = { a: 1, b: 2, c: 3 };
log(obj.keys());
deleteObject.prototype.keys;
functionmakeNinja(name) { }
functionmakeSamurai(name, rank) { }
log(makeNinja.length == 1);
log(makeSamurai.length == 2);
//overloadfunctionaddMethod(object, name, fn) {// Save a reference to the old method var old = object[ name ];
// Overwrite the method with our new one
object[ name ] = function() {// Check the number of incoming arguments, // compared to our overloaded function if ( fn.length == arguments.length )
// If there was a match, run the function return fn.apply( this, arguments );
// Otherwise, fallback to the old method elseif ( typeof old === "function" )
return old.apply( this, arguments );
};
}
appending
// call() takes any function arguments separately.// apply() takes any function arguments as an arrayMath.max(1, 2, 3);
Math.max.apply(null, [1, 2, 3]);
Math.max.call(null, 1, 2, 3);
//newarguments.callee
functionUser(first, last) {if ( !(thisinstanceofarguments.callee) )
returnnew User(first, last);
this.name = first + " " + last;
}
//Flexible Argumentsarguments代替function的参数
functionmerge(root) {for (var i = 1; i < arguments.length; i++)
for (var key inarguments[i])
root[key] = arguments[i][key];
return root;
}
var merged = merge({ name: "John" }, { city: "Bostonasd" });
assert(merged.name == "John", "The original name is intact.");
log(merged.city);
//slice 截取数组 //splice(1,1,array2)//var fruits = ["Banana", "Orange", "Apple", "Mango"];//fruits.slice.call(fruits, 1); //Orange,Apple,Mango//Array().splice.call(fruits,2, 1, "Lemon", "Kiwi"); //Banana,Orange,Lemon,Kiwi,MangofunctionmultiMax(multi) {// Make an array of all but the first argument var allButFirst = Array().slice.call( arguments, 1 );
// Find the largest number in that array of arguments var largestAllButFirst = Math.max.apply( Math, allButFirst );
// Return the multiplied result return multi * largestAllButFirst;
}
assert( multiMax(3, 1, 2, 3) == 9, "3*3=9 (First arg, by largest.)" );