<span style="font-size:18px;">function createComparisonFunction(propertyName) { return function (object1, object2) { var value1 = object1[propertyName]; var value2 = object2[propertyName]; if (value1 < value2) { return -1; } else if (value1 > value2) { return 1; } else { return 0; } }; } //创建函数 var compareNames = createComparisonFunction("name"); //调用函数 var result = compareNames({ name: "Nicholas" }, { name: "Greg" }); //解除对匿名函数的引用(以便释放内存) compareNames = null;</span>
作用域
<span style="font-size:18px;">// 一、定义函数的方式 // 1、函数声明 // 函数声明,它有重要特征就是函数声明提升(function declaration hoisting), // 即在执行代码之前会先读取函数声明。这就意味着可以把函数声明放在调用它的语句后面。 function funcName(arg1, arg2) { } console.info(funcName.name); // 2、函数表达式 // 这种情况下创建的函数叫做匿名函数(anonymous function),匿名函数有时候也叫拉姆达函数。 var funcName = function(arg1, arg2) { }; var sayWords; var condition = false; if (condition) { sayWords = function() { console.info("hello"); } } else { sayWords = function() { console.info("world"); } } // 二、将函数作为其他函数的值返回 function createComparisonFunction(propertyName) { return function (object1, object2) { var value1 = object1[propertyName]; var value2 = object2[propertyName]; if (value1 < value2) { return -1; } else if (value1 > value2) { return 1; } else { return 0; } }; } var people = []; for (var i = 0; i < 5; i++) { var person = new Object(); person.age = (i-2) * (i-2) - 3; person.name = "Jack"; people.push(person); } people.sort(createComparisonFunction("age")); console.info(people); // 三、递归 function factorial(num) { if (num <= 1) { return 1; } else { return num * factorial(num - 1); } } console.info("factorial(5):" + factorial(5)); var anotherFactorial = factorial; factorial = null; alert(anotherFactorial(4)); // 出错 // arguments.callee 是一个指向正在执行的函数的指针 // 在严格模式下,不能通过脚本访问arguments.callee function factorial(num) { if (num <= 1) { return 1; } else { return num * arguments.callee(num - 1); } } // 使用命名函数表达式 var factorial = (function f(num) { if (num <= 1) { return 1; } else { return num * f(num - 1); } }); // 四、闭包 // 闭包是指有权访问另一个函数作用域中的变量的函数。 // 由于闭包会携带包含它的函数的作用域,因此会比其他函数占用更多的内存。 // 4.1、闭包与变量 function createFuncs() { var result = new Array(); for (var i = 0; i < 10; i++) { result[i] = function() { return i; }; } return result; } // 闭包副作用,即闭包只能取得包含函数中任何变量的最后一个值。 var funcs = createFuncs(); for (var i = 0; i < funcs.length; i++) { console.info(funcs[i]()); } function createFuncs1(){ var result = new Array(); for (var i=0; i < 10; i++) { result[i] = function(num) { return function() { return num; }; }(i); } return result; } var funcs = createFuncs1(); for (var i = 0; i < funcs.length; i++) { console.info(typeof funcs[i]); console.info(funcs[i]()); } // 4.2 this对象 // this对象是在运行时基于函数的执行环境绑定的:在全局函数中,this等于window, // 而当函数被作为某个对象的方法调用时,this等于那个对象。 // 不过,匿名函数的执行环境具有全局性,因此其this对象通常指向window。 // 每个函数在被调用时都会自动取得两个特殊变量:this和arguments。 // 内部函数在搜索这两个变量时,只会搜索到其活动对象为止, // 因此永远不可能直接访问外部函数中的这两个变量。 var name = "The Window"; var object = { name: "My Object", getNameFunc: function(){ return function(){ return this.name; }; } }; console.info(object.getNameFunc()()); // "The Window"(在非严格模式下) var object = { name: "My object", getNameFunc: function() { var that = this; return function() { return that.name; } } } console.info(object.getNameFunc()()); // "My Object" // 4.3 内存泄露 function assignHandler(){ var element = document.getElementById("someElement"); element.onclick = function() { alert(element.id); }; } function assignHandler(){ var element = document.getElementById("someElement"); var id = element.id; element.onclick = function(){ alert(id); }; element = null; } // 五、模仿块级作用域 function outputNumbers(array, count) { for (var i = 0; i < count; i++) { console.info(array[i]); } console.info("i = ", i); // i = 5 } var arr = [1, 4, 6, 3, 7]; outputNumbers(arr, arr.length); function outputNumbers1(array, count) { for (var i = 0; i < count; i++) { console.info(array[i]); } var i; // 忽视该声明 console.info("i = ", i); // i = 5 } outputNumbers1(arr, arr.length); // JavaScript 没有块级作用域的概念,匿名函数可以用来模仿块级作用域。 (function(){ // 这里是块级作用域 })(); function outputNumbers(array, count) { (function () { for (var i = 0; i < count; i++) { console.info(array[i]); } })(); console.info("i = ", i); //导致一个错误! } (function() { var now = new Date(); if (now.getMonth() == 0 && now.getDate() == 1) { console.info("Happy new year!"); } })(); // 六、私有变量 // JavaScript中没有私有成员的概念;所有对象属性都是公有的。但有私有变量的概念。 // 任何在函数中定义的变量,都可以认为是私有变量。 // 私有变量包括函数的参数、局部变量和在函数内部定义的其他函数。 // 权访问私有变量和私有函数的公有方法称为特权方法(privileged method)。 // 利用闭包的作用域 // 1、实例变量 function MyObject() { // 私有变量和私有函数 var privateVariable = 10; function privateFunction() { return false; } // 特权方法 this.publicMethod = function () { privateVariable++; return privateFunction(); }; } function Person(name){ this.getName = function(){ return name; }; this.setName = function (value) { name = value; }; } var person = new Person("hello"); console.info(person.getName()); // "hello" person.setName("world"); console.info(person.getName()); // "world" // 2、静态私有变量 (function(){ // 私有变量和私有函数 var privateVariable = 10; function privateFunction(){ return false; } // 构造函数 MyObject = function(){ }; // 公有/特权方法 MyObject.prototype.publicMethod = function(){ privateVariable++; return privateFunction(); }; })(); (function(){ var name = ""; Person = function(value){ name = value; }; Person.prototype.getName = function(){ return name; }; Person.prototype.setName = function (value){ name = value; }; })(); var person1 = new Person("All"); console.info(person1.getName()); //"All" person1.setName("is"); console.info(person1.getName()); //"is" var person2 = new Person("well"); console.info(person1.getName()); //"well" console.info(person2.getName()); //"well" // 3、模块模式 // 通常JavaScript是以对象字面量的方式来创建单例对象的 var singleton = { name : value, method : function () { //这里是方法的代码 } }; // 模块模式通过为单例添加私有变量和特权方法能够使其得到增强。 // 如果必须创建一个对象并以某些数据对其进行初始化,同时还要公开一些能够访问这些私有 // 数据的方法,那么就可以使用模块模式。 var singleton = function() { // 私有变量和私有函数 var privateVariable = 10; function privateFunction() { return false; } //特权/公有方法和属性 return { publicProperty: true, publicMethod : function() { privateVariable++; return privateFunction(); } }; }(); var application = function() { //私有变量和函数 var components = new Array(); //初始化 components.push(new BaseComponent()); //公共 return { getComponentCount : function() { return components.length; }, registerComponent : function(component) { if (typeof component == "object") { components.push(component); } } }; }(); 1、增强的模块类型 // 对某种类型的实例进行加强 var singleton = function(){ //私有变量和私有函数 var privateVariable = 10; function privateFunction(){ return false; } //创建对象 var object = new CustomType(); //添加特权/公有属性和方法 object.publicProperty = true; object.publicMethod = function(){ privateVariable++; return privateFunction(); }; //返回这个对象 return object; }(); var application = function(){ //私有变量和函数 var components = new Array(); //初始化 components.push(new BaseComponent()); //创建application的一个局部副本 var app = new BaseComponent(); //公共接口 app.getComponentCount = function() { return components.length; }; app.registerComponent = function(component) { if (typeof component == "object") { components.push(component); } }; //返回这个副本 return app; }(); //有点像C#泛型中对类型参数的约束 internal class Base { public virtual void M<T1, T2>() where T1 : struct where T2 : class { } }</span>总结