javascript定义函数有3种方式:
//3种函数定义方式,前两种常用 /** * 1,function 语句式 * 形式:句子 * 名称:有名 * 性质:静态 * 解析时机:优先解析 * 作用域:具有函数的作用域(正常的作用域) */ function test01(){ alert("我是test01"); } //test01(); /** * 2,函数直接量 ECMAScript 推荐的方式 * 形式:表达式 * 名称:匿名 * 性质:静态 * 解析时机:顺序解析 * 作用域:具有函数的作用域(正常的作用域) */ var test02 = function(){ alert("我是test02"); }; //test02(); /** * 3,function 构造函数式,a,b是形参,函数执行体直接写在后边,以分号结束 * 形式:表达式 * 名称:匿名 * 性质:动态 * 解析时机:顺序解析 * 作用域:顶级函数(顶级作用域) */ var test03 = new Function("a","b","return a+b;"); //alert(test03(10,20));
区别:
1,效率方面对比,先new一个date,得到当前毫秒数,循环10万次,new10万个函数出来后,再得到当前毫秒,相减对比
//三种方式效率的对比 var d1 = new Date(); var t1 =d1.getTime(); for(var i=0;i<100000;i++){ function test1(){ ;}; //function语句式 //var test2 = new Function(); //构造函数式 } var d2 = new Date(); var t2 = d2.getTime(); alert(t2-t1);
可以看到function语句式比构造函数式效率要高,函数直接量和function语句式效率差不多。
原因:这就上边说的性质--静态和动态的区别,函数直接量和function语句式被javascript解释一次,放在了内存,以后用到的话直接调用,占用内存,所以说是“静态”的。而构造函数式是每一次调用都动态新建一个,用完之后就销毁了,不占用内存,所以说是“动态”的。所以,有些程序只希望调用一次,就可以用动态的构造函数式。
解析、执行顺序:
/** * ************************解析顺序*******************************************, * 对于function语句式的函数,javascript解析器会优先的解释 * javascript解析器会先看所有的全局变量,放到内存,test04()、test05会被当做全局变量 * test04()能正常执行,但是test05只有 */ //test04(); // function test04(){ // alert("test04"); // } //test05(); 执行不了,缺少对象 /** * undefined,表示变量声明了,没有被赋值, * 执行到此步时,还没有把function赋给test05,相当于先声明后赋值的概念 */ //alert(test05); var test05 = function(){ alert("test05"); }; //********************执行顺序经典例子************** /** * js解析器会先找所有的function当做全局变量放内存,就找到了1,4,静态的,4把1覆盖, * 执行到函数1,所以打印4 * 执行到函数2,是动态构建的覆盖4,所以打印2,之后销毁 * 执行到函数3,覆盖函数4,打印3 * 执行到函数4,其实调用的是函数3,打印3 * 执行到函数5,动态创建一个覆盖3,打印5,后销毁 * 执行到函数6,覆盖函数3,打印6 */ //alert结果:4 2 3 3 5 6 function f(){ return 1;} //函数1 alert(f()); //返回值为4,说明第1个函数被第4个函数覆盖, var f = new Function("return 2;"); //函数2 alert(f()); //返回值为2,说明第4个函数被第2个函数覆盖 var f = function(){ return 3;}; //函数3 alert(f()); //返回值为3,说明第4个函数被第3个函数覆盖 function f(){ return 4;} //函数4 alert(f()); //返回值为3,说明第4个函数被第3个函数覆盖 var f = new Function("return 5;"); //函数5 alert(f()); //返回值为5,说明第3个函数被第5个函数覆盖 var f = function(){ return 6;}; //函数6 alert(f()); //返回值为6,说明第3个函数被第6个函数覆盖
函数作用域:
/** * ******************函数作用域的概念************************* */ //var test = new Function("return k;"); var k = 1; function t1(){ var k = 2; //局部变量 //function test(){ return k; } //function语句式,k=2 //var test = function(){ return k;}; //函数直接量,k=2 ,两者都是函数的作用域 var test = new Function("return k;"); //构造函数,顶级的作用域,相当于在全局new一个函数,只能找到全局的k=1 alert(test()); } t1();
总结:
1,function语句式、函数直接量 就会被解释一次,是静态的,有函数的作用域,Function构造函数式每次执行都动态new一次,说明有顶级作用域。
2,解析机制,function语句式 相当于全局变量,会被优先解析,其他2种执行到哪解释到哪,顺序执行。
欢迎关注个人公众号一起交流学习: