//测试结果用 function assert(aBoolean, msg) { if (aBoolean && msg) document.write(msg + "<br/>"); } /*----------------------------- javascript中this比较搞,this是指函数的调用者 */ //功能很简单,返回this function creep() { return this; } //所有直接定义的函数其实都是window的方法,creep()等于window.creep(), //而this指的是调用creep的对象,这里就是window window.assert(creep() === window, "creep()===window"); //函数有括号是执行,没括号是赋值,不会执行函数,这就造成了如下的区别 var sneak = creep;//sneak指向creep这个函数,即sneak()与creep()效果一样。 var sneak2 = creep();//sneak2指向creep()返回的this assert(sneak() === window, "sneak()===window"); assert(sneak2 === window, "sneak2===window"); //ninja1对象的move属性指向creep函数 var ninja1 = { move : creep //即move : function(){return this;} }; //ninja1.move()返回的是ninja1对象,因为函数的调用者是ninja1 assert(ninja1.move() === ninja1, "ninja1.move()===ninja1"); var ninja2 = { move : ninja1.move }; //ninja2.move()返回的是ninja2对象,因为函数的调用者是ninja2 assert(ninja2.move() === ninja2, "ninja2.move()===ninja2"); /*----apply()和call()函数-----------*/ function sum() { var result = 0; for ( var n = 0; n < arguments.length; n++) { result += arguments[n]; } this.result = result; } sum(1, 2, 3, 4); //apply()和call()区别参数传入方式 sum.call(ninja1, 1, 2, 3, 4); sum.apply(ninja2, [ 1, 2, 3, 4 ]); //this分别指不同的对象 assert(window.result === 10, "window.result===10"); assert(ninja1.result === 10, "ninja1.result===10"); assert(ninja2.result === 10, "ninja2.result===10"); function forEach(list, callback) { for ( var n = 0; n < list.length; n++) { callback.call(list[n], n); } } var cb = function(index) { assert(this == weapons[index], "Got the expected value of " + weapons[index]); } var weapons = [ 'shuriken', 'katana', 'nunchucks' ]; forEach(weapons, cb);