背景知识

函数定义 
在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. Python练习笔记——计算输入日期为改年的第几天、星期几

    # 输入年月日,如:1995年12月10日,计算是该年的第几天?# 同时计算出当天是星期几? print("请依据提示依次输入您想查询的年 月 日") # 第一段代码块(年月日输入 ...

  2. 如何生成KeyStore

    介绍如何生成keystore cmd下: 进入到jdk的bin目录,这样的话,android.keystore文件就会生成在这个目录下,签名的时候我们需要这个文件. C:\Program Files\ ...

  3. GDI+绘制简单图形

    #include <windows.h>#include <gdiplus.h>using namespace Gdiplus;#pragma comment(lib, &qu ...

  4. [转]Hspice和Spice Explorer许可文件设置时环境变量FLEXLM_BATCH = 1的一些现象

    之前在T400上安装Spice Explorer时碰到运行Spice Explorer时只能看到Log界面,主程序界面自动消失的问题.后经论坛高手指点,在环境变量设置中去掉"FLEXLM_B ...

  5. 中国计算机学会CCF推荐国际学术期刊会议(最新版)

    中国计算机学会推荐国际学术期刊会议 2014年12月,中国计算机学会(CCF)启动新一轮<)计算机体系结构/高性能计算/存储系统: )计算机网络:)网络与信息安全:)软件工程/系统软件/程序设计 ...

  6. 【C语言】调整数组使奇数所有都位于偶数前面(改动)

    //调整数组使奇数全部都位于偶数前面. //输入一个整数数组.实现一个函数,来调整该数组中数字的顺序使得数组中全部的奇数位于数组的前半部分,全部偶数位于数组的后半部分 #include <std ...

  7. android购物车遇到的问题

    近期 做购物车的时候 ,遇到几个问题.如今 总结例如以下: 1:不让listview复用组件(购物车.或者有特殊操作的时候): 自己保存全部的view对象 public View getView(fi ...

  8. Linux系统CPU的性能监控及调优

    前言: 性能优化是一个老生常谈的话题,典型的性能问题如页面响应慢.接口超时,服务器负载高.并发数低,数据库频繁死锁等.尤其是在“糙快猛”的互联网开发模式大行其道的今天,随着系统访问量的日益增加和代码的 ...

  9. C++顺序容器vector、deque、list

    1.容器元素类型 C++中大多数数据类型能够作为容器的元素类型.容器元素类型必须满足一下两个条件:支持赋值和复制操作. 所以没有元素是引用类型的容器,同一时候IO对象和auto_ptr也不能作为容器的 ...

  10. JVM总结篇

    Sun HotSpot VM,是JDK和Open JDK中自带的虚拟机,也是目前使用范围最广的Java虚拟机. JVM内存分布 程序计数器:是一块较小的内存空间,可以看作是当前线程所执行的字节码的行号 ...