javascript
JavaScript学习随记——Function
? ? ? ?每個函數(shù)都是Function類型的實例,而且都與其他引用類型一樣具有屬性和方法。由于函數(shù)是對象,因此函數(shù)名實際上也是一個指向函數(shù)對象的指針,不會于某個函數(shù)綁定。
函數(shù)的定義方式
<script type="text/javascript" charset="utf-8">/*** 每個函數(shù)都是Function類型的實例,而且都與其他引用類型一樣具有屬性和方法。* 由于函數(shù)是對象,因此函數(shù)名實際上也是一個指向函數(shù)對象的指針,不會于某個函數(shù)綁定。* 函數(shù)通常是使用函數(shù)聲明語法定義的,如下面的列子所示:*//*** @example 1:函數(shù)聲明式定義函數(shù)* * * @param {Object} num1* @param {Object} num2*/function sum(num1,num2){return num1+num2;}/*** @example 2: 函數(shù)表達式式定義函數(shù)* * @param {Object} num1* @param {Object} num2* @note: 代碼聲明了一個sum變量并將其初始化為一個函數(shù)*/var sum = function(num1,num2){return num1+num2; };/*** @example 3:Function構(gòu)造函數(shù)定義函數(shù)(不推薦使用)* * @syntax : var functionName = Function("參數(shù)1","參數(shù)2","參數(shù)3",...,"函數(shù)體");* @note:Function構(gòu)造函數(shù)中最后一個參數(shù)是函數(shù)構(gòu)造的函數(shù)體,其他的參數(shù)是函數(shù)構(gòu)造的參數(shù)。* 從技術(shù)角度講,這是一個函數(shù)表達式。但是,我們不推薦使用這種方法定義函數(shù),因為這種語法會導(dǎo)致解析兩次代碼* (第一次是解析常規(guī)ECMAScript代碼,第二次是解析傳入函數(shù)中的字符串),從而影響性能。不過,這種語法對于理解* "函數(shù)是對象,函數(shù)名是指針"的概念是很非常直觀的。*/var sum = Function("num1","num2","return num1+num2;"); </script>
函數(shù)定義方式效率比較
<script type="text/javascript" charset="utf-8">//函數(shù)表達式式定義函數(shù)var start = Date.now();for(var i=0;i<10000;i++){var sum = function(num1,num2){return num1 + num2;};}var stop = Date.now();console.log("(10000次) 函數(shù)表達式式定義函數(shù),總耗時: "+(stop-start));var start = Date.now();for(var i=0;i<100000;i++){var sum = function(num1,num2){return num1+num2; };}var stop = Date.now();console.log("(100000次)函數(shù)表達式式定義函數(shù),總耗時: "+(stop-start));//函數(shù)聲明式定義函數(shù)var start = Date.now();for(var i=0;i<10000;i++){function sum(num1,num2){return num1+num2;}}var stop = Date.now();console.log("(10000次) 函數(shù)聲明式定義函數(shù),總耗時: "+(stop-start));var start = Date.now();for(var i=0;i<100000;i++){function sum(num1,num2){return num1+num2;}}var stop = Date.now();console.log("(100000次)函數(shù)聲明式定義函數(shù),總耗時: "+(stop-start));//Function構(gòu)造函數(shù)定義函數(shù)var start = Date.now();for(var i=0;i<100;i++){var sum = Function("num1","num2","return num1+num2;");}var stop = Date.now();console.log("(100次) Function構(gòu)造函數(shù)定義函數(shù),總耗時: "+(stop-start));var start = Date.now();for(var i=0;i<1000;i++){var sum = Function("num1","num2","return num1+num2;");}var stop = Date.now();console.log("(1000次)Function構(gòu)造函數(shù)定義函數(shù),總耗時: "+(stop-start));/********************* 【開始】運行結(jié)果 ********************(10000次) 函數(shù)表達式式定義函數(shù),總耗時: 6(100000次)函數(shù)表達式式定義函數(shù),總耗時: 47(10000次) 函數(shù)聲明式定義函數(shù),總耗時: 12(100000次)函數(shù)聲明式定義函數(shù),總耗時: 113(100次) Function構(gòu)造函數(shù)定義函數(shù),總耗時: 611(1000次)Function構(gòu)造函數(shù)定義函數(shù),總耗時: 5095********************* 【結(jié)束】運行結(jié)果 ********************/ </script>
不同定義方式的函數(shù)解析執(zhí)行順序
<script type="text/javascript" charset="utf-8">/*** 解析器在向執(zhí)行環(huán)境中加載數(shù)據(jù)時,對函數(shù)聲明和函數(shù)表達式并非一視同仁。* 解析器會率先讀取函數(shù)聲明,并使其在執(zhí)行任何代碼之前可用(可以訪問);* 至于函數(shù)表達式,則必須等到解析器執(zhí)行到它所在的代碼行,才會真正被解析器執(zhí)行。* * 例子如下:* 例子分析:受執(zhí)行順序的影響,(函數(shù)是對象,函數(shù)名是指針)getName被后執(zhí)行的表達式式定義的函數(shù)覆蓋*/var getName = function(){return "李四";};console.log(getName());function getName(){return "張三";}console.log(getName());/********************* 【開始】運行結(jié)果 ********************李四李四********************* 【結(jié)束】運行結(jié)果 ********************/ </script>
函數(shù)共有的屬性和方法
?? ?? 屬性:
?? ? ??? ??? ?1、length:值為函數(shù)希望接受的參數(shù)的個數(shù);
?? ? ??? ??? ?2、caller:保存著調(diào)用當(dāng)前函數(shù)的函數(shù)的引用;
?? ? ??? ??? ?3、prototype:每個函數(shù)都有一個prototype屬性,這個屬性是指向一個對象的引用,這個對象稱為原型對象,原型對象包含函數(shù)實例共享的方法和屬性,也就是說將函數(shù)用作構(gòu)造函數(shù)調(diào)用(使用new操作符調(diào)用)的時候,新創(chuàng)建的對象會從原型對象上繼承屬性和方法。在ECMAScript 5 中,prototype 屬性是不可枚舉的。
?? ?? 方法:
?? ? ??? ??? ?1、apply(socpe,argyArray):在特定的作用域中調(diào)用函數(shù),實際上等于設(shè)置函數(shù)體內(nèi)this對象的值。
?? ? ??? ??? ??? ?第一個參數(shù)(scope)表示運行函數(shù)的作用域,第二個參數(shù)是一個Array實例,也可以是arguments對象(函數(shù)調(diào)用時的參數(shù))。
?? ? ??? ??? ?2、call(scope,arg1,arg2,arg3....):在特定的作用域中調(diào)用函數(shù),實際上等于設(shè)置函數(shù)體內(nèi)this對象的值。
?? ? ??? ??? ??? ?第一個參數(shù)(scope)表示運行函數(shù)的作用域,后面的參數(shù)都是函數(shù)調(diào)用時的參數(shù)。
<script type="text/javascript" charset="utf-8">/*** arguments 它是一個類似數(shù)組對象,包含著傳入函數(shù)中的所有參數(shù)。*/function sum(){var total = 0;for(var i=0;i<arguments.length;i++){total+=arguments[i];}return total;}console.log("sum(1): "+sum(1));console.log("sum(1,2): "+sum(1,2));console.log("sum(1,2,3): "+sum(1,2,3));console.log("sum(1,2,3,4): "+sum(1,2,3,4));/********************* 【開始】運行結(jié)果 ********************sum(1): 1sum(1,2): 3sum(1,2,3): 6sum(1,2,3,4): 10********************* 【結(jié)束】運行結(jié)果 ********************/ </script>
<script type="text/javascript" charset="utf-8">/*** 定義階乘函數(shù)* @param {Object} num* * @note: 下面定義階乘的函數(shù)例子中,函數(shù)名字與函數(shù)執(zhí)行體存在緊密的耦合* 在一起,因此想用其他的函數(shù)名時則需要修改函數(shù)體代碼。JavaScript提供* 了一種方式消除這種緊密耦合現(xiàn)象,就是使用 arguments.callee*/function factorial(num){if(num <= 1){return 1;}else{return num*factorial(num-1);}}console.log("factorial(5): "+factorial(5));/*** 定義階乘函數(shù)(函數(shù)名與代碼體無耦合關(guān)系)* arguments.callee: arguments的屬性,保存著arguments的所屬函數(shù)的引用,即 arguments.callee 等價于 arguments對象所屬函數(shù)。* @param {Object} num*/function factorial1(num){if(num <= 1){return 1;}else{return num * arguments.callee(num-1);}}console.log("factorial1(5): "+factorial1(5));/********************* 【開始】運行結(jié)果 ********************factorial(5): 120factorial1(5): 120********************* 【結(jié)束】運行結(jié)果 ********************/ </script>
<script type="text/javascript" charset="utf-8">/*** function 中this指向的是函數(shù)的調(diào)用者,即誰調(diào)用了函數(shù)this就代表誰;*/window.name = "我乃是window";var zhangsan = {name:"我乃是張三"};var lisi = {name:"我是李四"};function getName(){return this.name;}console.log(getName.call(this));console.log(getName.call(window));console.log(getName.call(zhangsan));console.log(getName.call(lisi));/********************* 【開始】運行結(jié)果 ********************我乃是window我乃是window我乃是張三我是李四********************* 【結(jié)束】運行結(jié)果 ********************/ </script>
總結(jié)
以上是生活随笔為你收集整理的JavaScript学习随记——Function的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: JavaScript学习随记——常见全局
- 下一篇: JavaScript学习随记——属性类型