javascript
JavaScript Function中你可能不知道的知识点
目錄
函數(shù)的聲明
函數(shù)的屬性與特性??
函數(shù)作用域
函數(shù)參數(shù)的傳遞方式
arguments 對(duì)象
閉包
函數(shù)是一段可以反復(fù)調(diào)用的代碼塊。函數(shù)還能接受輸入的參數(shù),不同的參數(shù)會(huì)返回不同的值。
函數(shù)的聲明
- function命令
- ?函數(shù)表達(dá)式
- ?Function 構(gòu)造函數(shù)
?你可以傳遞任意數(shù)量的參數(shù)給Function構(gòu)造函數(shù),只有最后一個(gè)參數(shù)會(huì)被當(dāng)做函數(shù)體,如果只有一個(gè)參數(shù),該參數(shù)就是函數(shù)體。
函數(shù)的屬性與特性??
- name屬性
函數(shù)的name屬性返回函數(shù)的名字。
function f1() {} f1.name // "f1"// 如果是通過(guò)變量賦值定義的函數(shù),那么name屬性返回變量名。 var f2 = function () {}; f2.name // "f2"- ?leng屬性
函數(shù)的length屬性返回函數(shù)預(yù)期傳入的參數(shù)個(gè)數(shù),即函數(shù)定義之中的參數(shù)個(gè)數(shù)。
function f(a, b) {} f.length // 2不管調(diào)用時(shí)傳入多少個(gè)參數(shù),leng屬性值始終等于2,length屬性就是定義時(shí)的參數(shù)個(gè)數(shù),與調(diào)用無(wú)關(guān)。
- 函數(shù)名提升
JavaScript 引擎將函數(shù)名視同變量名,所以采用function命令聲明函數(shù)時(shí),整個(gè)函數(shù)會(huì)像變量聲明一樣,被提升到代碼頭部。所以,下面的代碼不會(huì)報(bào)錯(cuò)。
f();function f() {}函數(shù)作用域
作用域分全局作用域 和 函數(shù)作用域,全局作用域,變量在整個(gè)程序中一直存在,所有地方都可以讀取;函數(shù)作用域,變量只在函數(shù)內(nèi)部存在。
- 在函數(shù)內(nèi)部定義的變量,外部無(wú)法讀取,稱為“局部變量”。
- 函數(shù)內(nèi)部定義的變量,會(huì)在該作用域內(nèi)覆蓋同名全局變量。
- 函數(shù)作用域內(nèi)部也會(huì)產(chǎn)生“變量提升”現(xiàn)象。var命令聲明的變量,不管在什么位置,變量聲明都會(huì)被提升到函數(shù)體的頭部
? - ?函數(shù)本身也是一個(gè)值,也有自己的作用域。就是其聲明時(shí)所在的作用域,與其運(yùn)行時(shí)所在的作用域無(wú)關(guān)(與調(diào)用無(wú)關(guān))。
函數(shù)參數(shù)的傳遞方式
- 函數(shù)參數(shù)如果是原始類型的值(數(shù)值、字符串、布爾值),傳遞方式是傳值傳遞
這意味著,在函數(shù)體內(nèi)修改參數(shù)值,不會(huì)影響到函數(shù)外部。
var p = 2;function f(p) {p = 3; } f(p);p // 2- ?函數(shù)參數(shù)是復(fù)合類型的值(數(shù)組、對(duì)象、其他函數(shù)),傳遞方式是傳址傳遞。
也就是說(shuō),傳入函數(shù)的原始值的地址,因此在函數(shù)內(nèi)部修改參數(shù),將會(huì)影響到原始值。
var obj = { p: 1 };function f(o) {o.p = 2; } f(obj);obj.p // 2?如果函數(shù)內(nèi)部修改的,不是參數(shù)對(duì)象的某個(gè)屬性,而是替換掉整個(gè)參數(shù),這時(shí)不會(huì)影響到原始值。
var obj = [1, 2, 3];function f(o) {o = [2, 3, 4]; } f(obj);obj // [1, 2, 3]這是因?yàn)?#xff0c;形式參數(shù)(o)的值實(shí)際是參數(shù)obj的地址,重新對(duì)o賦值導(dǎo)致o指向另一個(gè)地址,保存在原地址上的值當(dāng)然不受影響。
就是說(shuō) o 其實(shí)作為參數(shù)代表數(shù)組 [1,2,3] 的地址,又被賦予了 [2,3,4] 的地址,所以不會(huì)影響到 obj。
arguments 對(duì)象
- 由于 JavaScript 允許函數(shù)有不定數(shù)目的參數(shù),所以需要一種機(jī)制,可以在函數(shù)體內(nèi)部讀取所有參數(shù)。這就是arguments對(duì)象的由來(lái)。
arguments對(duì)象包含了函數(shù)運(yùn)行時(shí)的所有參數(shù),arguments[0]就是第一個(gè)參數(shù),arguments[1]就是第二個(gè)參數(shù),以此類推。這個(gè)對(duì)象只有在函數(shù)體內(nèi)部,才可以使用。
- 雖然arguments很像數(shù)組,但它是一個(gè)對(duì)象。數(shù)組專有的方法(比如slice和forEach),不能在arguments對(duì)象上直接使用。
? - arguments對(duì)象帶有一個(gè)callee屬性,返回它所對(duì)應(yīng)的原函數(shù)。
閉包
理解閉包,首先必須理解變量作用域。前面提到,JavaScript 有兩種作用域:全局作用域和函數(shù)作用域。函數(shù)內(nèi)部可以直接讀取全局變量。但是函數(shù)外部無(wú)法讀取函數(shù)內(nèi)部聲明的變量。出于種種原因,需要得到函數(shù)內(nèi)的局部變量。正常情況下,這是辦不到的,只有通過(guò)變通方法才能實(shí)現(xiàn)。那就是在函數(shù)的內(nèi)部,再定義一個(gè)函數(shù)。
function f1() {var n = 999;function f2() {console.log(n);}return f2; }var result = f1(); result(); // 999上面代碼中,函數(shù)f1的返回值就是函數(shù)f2,由于f2可以讀取f1的內(nèi)部變量,所以就可以在外部獲得f1的內(nèi)部變量了。
閉包就是函數(shù)f2,由于在 JavaScript 語(yǔ)言中,只有函數(shù)內(nèi)部的子函數(shù)才能讀取內(nèi)部變量,因此可以把閉包簡(jiǎn)單理解成“定義在一個(gè)函數(shù)內(nèi)部的函數(shù)”。
閉包的最大用處用兩個(gè):
為什么閉包能夠返回外層函數(shù)的內(nèi)部變量:
閉包用到了外層變量,導(dǎo)致外層函數(shù)不能從內(nèi)存釋放。只要閉包沒(méi)有被垃圾回收機(jī)制清除,外層函數(shù)提供的運(yùn)行環(huán)境也不會(huì)被清除,它的內(nèi)部變量就始終保存著當(dāng)前值,供閉包讀取。
總結(jié)
以上是生活随笔為你收集整理的JavaScript Function中你可能不知道的知识点的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 如何评价谭浩强(转自知乎)
- 下一篇: 【Spring注解驱动开发】二狗子让我给