JavaScript学习笔记(十三) 返回函数和"自定义"函数
2012-10-03 05:49
645 查看
返回函数(Returning Functions)
函数是对象,所以它们可以被当做返回值;这意味着一个函数不一定要返回某种数据或数据的数组作为它的返回值;
一个函数可以返回另一个更加专业的函数,或者依赖于输入返回一个合适的函数;
这里有个例子:一个函数做了一些工作,可能是一些一次性的初始化的工作,然后在返回值上继续工作,返回值恰巧是另外一个函数,可以被执行:
var setup = function() { alert(1); return function() { alert(2); }; }; // using the setup function var my = setup(); // alerts 1 my(); // alerts 2因为setup()包裹了返回的函数,它创建了一个闭包(closure),所以你可以使用这个闭包去存储一些私有的变量;
这些私有变量是可以被返回的函数访问的,但在这段代码外面就访问不到了;
一个计数器的例子,每次调用都会加1:
var setup = function() { var count = 0; return function() { return (count += 1); }; }; // usage var next = setup(); next(); // returns 1 next(); // 2 next(); // 3
自定义函数(Self-Defining Functions)
函数可以动态的被定义并且可以赋值给变量。如果你创建了一个新的函数并赋值给一个已经保存着另外一个函数的变量,你会用新的函数覆盖旧的函数;
在某种程度上,你正在回收利用旧的函数指针(引用)指向新的函数,并且所有的这些过程都可以在旧函数的函数体中发生;
在这种情况下,函数被覆盖并且用一个新的实现重新定义它自己;
这听起来可能比实际更难懂,让我们看一个简单的例子:
var scareMe = function() { alert("Boo!"); scareMe = function() { alert("Double boo!"); }; }; // using the self-defining function scareMe(); // Boo! scareMe(); // Double boo!这种模式非常有用,当你的函数有一些初始化的准备工作要去做并且只需要做一次(在可以避免的情况下,没有理由去做重复的工作),函数的一部分可能再也不需要了;
在这种情况下,自定义函数可以更新它自己的实现。
使用这种模式可以显著的提高你的程序的性能,因为你重定义的函数会做了更少的工作。
这种模式另外一个名称就是"惰性函数定义(lazy function definition)",因为函数没有被“正确”的定义直到第一次被使用的时候,然后它就变懒了,做更少的工作。
这种模式一个缺点就是当它重定义它自己的之后,你给最初的函数添加的任何属性都会丢失;
如果函数和不同的名称一起使用,比如,赋值给不同的变量或者被作为一个对象的方法,那么重定义部分将不会发生并且最初的函数体将会被执行;
让我们来看一个例子,scareMe()函数被当做一个的对象使用:
添加一个新属性
函数对象被赋值给新的变量
函数被当做对象的一个方法
// 1. adding a new property scareMe.property = "properly"; // 2. assigning to a different name var prank = scareMe; // 3. using as a method var spooky = { boo: scareMe }; // calling with a new name prank(); // "Boo!" prank(); // "Boo!" console.log(prank.property); // "properly" // calling as a method spooky.boo(); // "Boo!" spooky.boo(); // "Boo!" console.log(spooky.boo.property); // "properly" // using the self-defined function scareMe(); // Double boo! scareMe(); // Double boo! console.log(scareMe.property); // undefined正如你看到的,当函数被赋值给一个新的变量后,你期待的自我定义就不会发生,每一次prank()被调用,会提示"BOO!";
同时,它也会重写全局的scareMe()函数,但prank()它自己看到的仍然还是旧的定义包括property属性;
当调用spooky对象的boo()方法时,也会发生相同的事情,所以这些调用都会重写全局的scareMe()指针;
当scareMe()最后被调用的时候,它的实现已经被更新,所以从一开始就提示”Double boo!“,再也看不到scareMe.property了。
相关文章推荐
- ASP.NET学习笔记(5)--"返回上一页"功能的实现
- javascript学习笔记——如何修改<a href="#">url name</a>
- JavaScript学习笔记之数据类型和("32"+32)和("32"-32)输出结果
- JavaScript 学习笔记(八).innerHTML、onblur="……"、密码强度
- JavaScript 学习笔记(三)window.open (……)、window.confirm("**")、window.status="**"、reload()、href('**')、go(*)
- JavaScript 学习笔记(四)…….style.display="none"、……"block"、list-style、href="javascript:……"、…….className
- JavaScript 学习笔记(六)with(field) {……value.indexOf("@");……}、.focus()
- Sharepoint学习笔记-- Debug&TroubleShooting--调试Sharepoint环境中的Javascript/ECMAScript
- javascript学习笔记之函数定义
- 【Python】学习笔记十三:函数的参数对应
- 自定义std::sort的比较函数时发生"invalid operator<"错误原因
- JavaScript高程学习笔记之函数表达式(7)
- [原]java专业程序代写(qq:928900200),学习笔记之基础入门<Oracle_函数_触发器_游标_存储过程_视图>(三十五)
- spring scope="prototype" 学习笔记
- SQL Server BUG集之"自定义函数与group by"
- javascript学习笔记(七) js函数介绍
- 逆向工程核心原理学习笔记(二十):栈帧7:删除函数add()的栈帧&函数返回
- 函数功能:传入一个数组,返回数组中第二大数。已知数组中的对象都是数字构成的字符串,且任意两元素不相等。 如传入:@[@"1",@"2",@"3",@"4"],返回@"3"
- c++学习笔记之函数引用返回
- JavaScript学习笔记(十三)---- 表单事件