背景知识

函数定义 
在javaScript中,function的定义有3种:

1、匿名定义 
               function(){}

2、非匿名定义 
               function fn(){} 
               fn = new Function();

触发函数执行 
对于匿名函数: 
                       (function(){})();       //执行一个匿名函数 
                       var f = function(){}(); //执行一个匿名函数,并将匿名函数的返回值,赋值给f 
                       !function(){}();        //执行一个匿名函数 
                  
              以上三种写法, 
              无非就是要把 匿名函数 作为一个表达式块 然后执行。

对于非匿名函数: 
                       函数名();       //如: fn();

用法示例 
例子 1 
function add(x, y){ 
   return(x + y);  

例子 2 
var add = new Function("x", "y", "return(x+y)");

例子 3 
var fn = function(){ }  
将匿名函数的引用赋值给一个变量。(最常用的写法)如:

var add = function(x, y){ 
   return(x + y);  

---------------------------------------------------------------- 
可以用如下代码行调用以上函数: 
add(2, 3);

注意 : 在调用函数时,请确保包含了括号和必需的参数。调用函数时不用括号导致返回函数的文本而不是函数执行的结果。 
add(2, 3);// return  "5" 
add;      // renturn  " function add(x, y){return(x + y);}

1、用法剖析

  1. <html>
  2. <head>
  3. <style type="text/css">
  4. p{
  5. #CCCCCC;
  6. height:20px;
  7. width:100px;
  8. }
  9. </style>
  10. </head>
  11. <body >
  12. <p>test</p>
  13. <p>test</p>
  14. <p>test</p>
  15. <p>test</p>
  16. <p>test</p>
  17. <p>test</p>
  18. <script type="text/javascript">
  19. /********************Method 1********************************/
  20. //常规的写法(正确的写法)
  21. /*
  22. var item=document.getElementsByTagName('p');
  23. for(var i=0;i<item.length;i++){
  24. item[i].onclick=(function(i){
  25. return function(){
  26. alert(i);
  27. }
  28. })(i);
  29. }
  30. */
  31. /********************Method 2********************************/
  32. //所有的 p 都 alert() 最后一个 i 的值(错误的写法)
  33. /*
  34. var item=document.getElementsByTagName('p');
  35. for(var i=0;i<item.length;i++){
  36. item[i].onclick=function(){
  37. alert(i);
  38. };
  39. }
  40. */
  41. /*
  42. 说明:
  43. item[i].onclick=(function(){})(); 匿名函数与立即执行 ,然后把结果给item[i].onclick
  44. */
  45. /********************Method 3********************************/
  46. //最能表达含义的写法(正确的写法)
  47. function createFunction(index){
  48. return function(){
  49. alert(index);
  50. }
  51. }
  52. var elems = document.getElementsByTagName('p');
  53. for(var i=0,len=elems.length; i<len; i++){
  54. elems[i].onclick = createFunction(i);
  55. }
  56. /*说明:
  57. return function(){
  58. alert(letter);
  59. }
  60. =
  61. return var fn = new Function(){
  62. alert(letter);
  63. }
  64. 调用 function ,生成(定义)function.
  65. renturn 的 时候其实是 new 了一个function 出来。
  66. */
  67. </script>
  68. </body>
  69. </html>

2、运行效果图

3、深入理解js的dom机制

js的一切对象(包括函数)都是依赖于 html的dom而存在的。

默认对象是window,所有的方法、属性,默认都是window对象的属性和方法 
--------------------------- 
alert() = window.alert() 
--------------------------- 
var x = window.x 
var x = 10; 
alert(window.x ); //10

我们猜测所有js函数运行时的环境,也是基于某个对象的(该对象的属性就是其运行环境)。

请看下面的例子:

例子一

  1. <html>
  2. <head>
  3. <style type="text/css">
  4. p{
  5. width:200px;
  6. height:30px;
  7. }
  8. </style>
  9. </head>
  10. <body>
  11. <p>test </p>
  12. <p>test </p>
  13. <p>test </p>
  14. <p>test </p>
  15. <p>test </p>
  16. <p>test </p>
  17. <script type="text/javascript">
  18. window.onload=function(){
  19. var adiv=document.getElementsByTagName('p');
  20. for(var i=0;i<adiv.length;i++){
  21. adiv[i].onclick=function(){
  22. alert(i);
  23. }
  24. }
  25. }
  26. </script>
  27. </body>
  28. </html>

结果:(无论点那个都alert 6)

例子二

  1. <html>
  2. <head>
  3. <style type="text/css">
  4. p{
  5. width:200px;
  6. height:30px;
  7. }
  8. </style>
  9. </head>
  10. <body>
  11. <p>test </p>
  12. <p>test </p>
  13. <p>test </p>
  14. <p>test </p>
  15. <p>test </p>
  16. <p>test </p>
  17. <script type="text/javascript">
  18. window.onload=function(){
  19. var adiv=document.getElementsByTagName('p');
  20. for(var i=0;i<adiv.length;i++){
  21. adiv[i].onclick=(function(i){
  22. return function(){ alert(i);};
  23. })(i);
  24. }
  25. }
  26. </script>
  27. </body>
  28. </html>

结果:(正常)

原因:

在例子二中, 
改变了onclick事件的function的作用域范围。 
(function(){ 
    return fuction(){}; 
})(); 
新new了一个function作用域,赋值给onclick事件。

分析:

例子一: 
当onclick触发时,它实际(引用)运行的环境是 window.onload , 
window.onload是一个function,而它又有自己的属性: 
window.onload.adiv 
window.onload.i 
window.onload.adiv[0].onclick 
window.onload.adiv[1].onclick 
window.onload.adiv[2].onclick 
window.onload.adiv[3].onclick 
...

onclick 会在当前作用域中找adiv(找到了) ,也会去找 i ,但是此时 i 的值 是 adiv.leng-1 
所以会一直 alert 一个值

而如下方式(例子二): 
window.onload=function(){ 
    var adiv=document.getElementsByTagName('p'); 
    for(i=0;i<adiv.length;i++){ 
        adiv[i].onclick=(function(i){ 
            return function(){alert(i)}; 
        })(i); 
        } 
    } 

是采用匿名函数立即执行,利用立即执行为匿名函数,window.onload为自身创建属性(一个匿名函数) 
此匿名又有2个属性(一个参数i,一个funcion) 
并把执行后的结果赋值给 adiv[i].onclick 
此时window.onload的结构大致是: 
window.onload.adiv 
window.onload.i 
window.onload.adiv[0].onclick 
window.onload.(function(0){}) 
window.onload.(function(0){}).i 
window.onload.(function(0){}).function

window.onload.adiv[1].onclick 
window.onload.(function(1){}) 
window.onload.(function(1){}).i 
window.onload.(function(1){}).function

...

赋值后 
window.onload.adiv[0].onclick = 
window.onload.(function(0){}).function

此时adiv[0].onclick的作用域是:window.onload.(function(0){}) 
                 不再是原来的:window.onload

在新的作用域中是有 i 的,而 i 的值,就是当初传进来的值。

再看下面的例子:

  1. <html>
  2. <head>
  3. <style type="text/css"></style>
  4. </head>
  5. <body>
  6. <script type="text/javascript">
  7. /*
  8. //1.
  9. function Wen(){
  10. this.name = "taobao";
  11. this.waitMes=function(){
  12. setTimeout(function(){this.fn(this.name);},1000);
  13. };
  14. this.fn=function(name){
  15. alert(name);
  16. }
  17. }
  18. var foo=new Wen();
  19. foo.waitMes();
  20. //**运行结果:空。
  21. // *因为setTimeout 运行时的上下文环境是window
  22. // *而 window 没有 fn 和 name 属性
  23. //**故alert值为空
  24. //2.
  25. var name = "taobao";
  26. function fn (name){
  27. alert(name);
  28. }
  29. function Wen(){
  30. this.waitMes=function(){
  31. setTimeout(function(){this.fn(this.name);},1000);
  32. };
  33. }
  34. var foo=new Wen();
  35. foo.waitMes();
  36. //**运行结果:非空。
  37. // *将 fn 和 name 放在 window 对象下
  38. //3.
  39. function Wen(){
  40. this.name = "taobao";
  41. this.waitMes=function(){
  42. var that = this;
  43. setTimeout(function(){that.fn(that.name);},1000);
  44. };
  45. this.fn=function(name){
  46. alert(name);
  47. }
  48. }
  49. var foo=new Wen();
  50. foo.waitMes();
  51. //**运行结果:非空。
  52. // *that作为参数传递到this中
  53. */
  54. //4.
  55. function Wen(){
  56. this.name = "taobao";
  57. this.waitMes=function(){
  58. var that = this;
  59. setTimeout(that.fn,1000);
  60. };
  61. this.fn=function(){
  62. alert(this.name);
  63. };
  64. }
  65. var foo=new Wen();
  66. foo.waitMes();
  67. //**运行结果:非空。
  68. // *that作为参数传递到this中
  69. </script>
  70. </body>
  71. </html>

4、变量作用域之 变量覆盖

原理: 
由于js function对象的 hoisting 特性(函数内的所有变量都相当于自动在函数头部声明,赋值部分位置不变), 
可能会导致访问变量时出现 undefined。

例子:

  1. <script type="text/javascript">
  2. //1.
  3. var foo = 'This is foo.';
  4. (function(){
  5. alert(foo);//This is foo.
  6. })();
  7. //2.
  8. var foo = 'This is foo.';
  9. (function(){
  10. alert(foo);//undefined
  11. var foo = 2;
  12. })();
  13. /**
  14. function对象的 hoisting 特性:函数内的所有变量都相当于自动在函数头部声明
  15. 故 2 等价于这种写法:
  16. var foo = 'This is foo.';
  17. (function(){
  18. var foo;
  19. alert(foo);
  20. foo = 2;
  21. })();
  22. 在2中,又定义了一个局部变量foo,(覆盖了上级范围的foo),但是没有给赋初值,
  23. 故访问foo时,出现 undefined 提示。
  24. */
  25. </script>

所以,在函数定义时,其所有用到的变量,要写在函数体前。

补录: 
--- 
匿名函数自动执行,只是一种简便的写法而已,并无新奇或创意。 
(function(){})(); 
等价于 
var fn = function(){}; 
fn();//执行 
在任何使用过程中,完全可以用后一种方式替代。

javaScript之function定义的更多相关文章

  1. JavaScript jQuery 中定义数组与操作及jquery数组操作

    首先给大家介绍javascript jquery中定义数组与操作的相关知识,具体内容如下所示: 1.认识数组 数组就是某类数据的集合,数据类型可以是整型.字符串.甚至是对象Javascript不支持多 ...

  2. JavaScript笔记 Function

    在JavaScript中方法由两部分组成: 方法名和方法体. JavaScript中的方法跟其他传统面向对象语言不同,它跟普通的变量没有区别,唯一不同点是它是Function对象,因此它会有一些Fun ...

  3. javascript函数的定义与执行

    要理解javascript函数的定义与执行,首先需要知道这几个重要的概念,现在可以先知道稍后再理解! 函数的执行环境(excution context).活动对象(call object).作用域(s ...

  4. (转)深入理解javascript的function

    原文:http://www.cnblogs.com/sharpxiajun/archive/2011/09/16/2179323.html javascript笔记:深入理解javascript的fu ...

  5. javascript的Function 和其 Arguments

    http://shengren-wang.iteye.com/blog/1343256 javascript的Function属性:1.Arguments对象2.caller 对调用单前函数的Func ...

  6. JavaScript的function对象

    我必须先说Java与JavaScript没有关系,不是我以前想的那个样子的(JavaScript是Java的一种超进化) 在JavaScript中,函数(function)就是对象. JavaScri ...

  7. Javascript函数(定义、传值、重载)

    Javascript 函数的定义的方式有不止一种. 第一种方式: function fn1(){ alert(typeof fn1); alert(“fn1”); } 在调用的时候直接就可以fu1() ...

  8. JavaScript之Function函数深入总结

    整理了JavaScript中函数Function的各种,感觉函数就是一大对象啊,各种知识点都能牵扯进来,不单单是 Function 这个本身原生的引用类型的各种用法,还包含执行环境,作用域,闭包,上下 ...

  9. JavaScript Nested Function 的时空和身份属性

    JavaScript 的function 不仅仅是一等公民,简直就是特殊公民.它有许多独特的特征: 1) 它是object,可以存储,传递,附加属性. 2) 它可以有lexical closure, ...

随机推荐

  1. C语言笔记本

    在此记录一些常见的C语言错误,可以当作学习C语言的笔记,需要的时候可以回过头看看. 1.关于“++” #include int main() { int a,b,cd; a=10; b=a++; c= ...

  2. posix 条件变量与互斥锁 示例生产者--消费者问题

    一.posix 条件变量 一种线程间同步的情形:线程A需要等某个条件成立才能继续往下执行,现在这个条件不成立,线程A就阻塞等待,而线程B在执行过程中使这个条件成立了,就唤醒线程A继续执行. 在pthr ...

  3. Shell中重定向&lt;&lt;EOF注意事项

    作者:iamlaosong 我们常常在shell脚本程序中用<<EOF重定向输入.将我们输入的命令字符串作为一个运行程序的输入,这样,我们就不须要在那个程序环境中手工输入命令,以便自己主动 ...

  4. lua——元表、元方法、继承

    [元表] 元表中的键为事件(event),称值为元方法(metamethod). 通过函数getmetatable查询不论什么值的元表,通过函数setmetatable替换表的元表. setmetat ...

  5. JSP页面中文乱码

    近期搭建了一个JAVA WEB项目,引入了国际化的ResourceBundle. 顺便赞一个,Eclipse Mars,自带了中文转unicode编码的功能. ① 根据语言选择,初始化Resource ...

  6. echarts geo地图坐标转换为页面Offset坐标

    https://github.com/apache/incubator-echarts/issues/2540 代码示例: // 获取系列 ) // 获取地理坐标系实例 var coordSys = ...

  7. 《Effective Java》读书笔记二(通用方法)

    No8 覆盖equals方法时请遵守通用约定 通用约定,下面的约定前提都是x/y/z不为null值. 自反性(reflexive),x.equals(x)必须返回true. 对称性(symmetric ...

  8. [Jobdu] 题目1516:调整数组顺序使奇数位于偶数前面

    题目描述: 输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有的奇数位于数组的前半部分,所有的偶数位于位于数组的后半部分,并保证奇数和奇数,偶数和偶数之间的相对位置不变. 输入: 每个输 ...

  9. 每天一点儿Java--ComboBox

    import java.awt.*; import java.awt.event.*; import javax.swing.*; import javax.swing.border.*; impor ...

  10. git使用(二)----创建版本库

    创建版本库(操作都是在linux环境下) 什么是版本库呢?版本库又名仓库,英文名repository,其实就是一个目录,可以进行增删查改 创建一个目录,这里在根目录下创建一个git_home目录mkd ...