摘要:在向參數(shù)傳遞引用類型的值時,會把這個值在內(nèi)存中的地址復(fù)制給一個局部變量,因此這個局部變量的變化會反映在函數(shù)的外部。當(dāng)在函數(shù)內(nèi)部重寫時,這個變量的引用就是一個局部變量了,這個局部變量在函數(shù)執(zhí)行完畢后立即銷毀。
前言:我入門學(xué)的 java這種強(qiáng)類型語言,剛開始學(xué)js第一感覺是挺簡單,后來發(fā)現(xiàn)還是too young。所以,本次就把作用域、匿名函數(shù)做一個完整總結(jié),黑喂狗~~~
-------------------分割線----------------------
1.函數(shù) 返回值/參數(shù)返回值:::::::::::::::::::::::::
js的函數(shù)在定義時不必指定返回值,而且任何函數(shù)都可以通過return隨時返回值。
函數(shù)在執(zhí)行完return之后停止并立即退出,因此return后面的代碼永遠(yuǎn)不會執(zhí)行。
function sum(num1,num2){ return num1 + num2; alert("Hello World"); //這段代碼永遠(yuǎn)不會執(zhí)行 }
參數(shù):::::::::::::::
js函數(shù)不介意傳遞進(jìn)來多少個參數(shù),也不在乎傳遞進(jìn)來的是什么參數(shù)類型。
參數(shù)在內(nèi)部是由一個數(shù)組來表示的,函數(shù)接收的永遠(yuǎn)都是這個數(shù)組,函數(shù)體內(nèi)部可以通過arguments對象來訪問這個參數(shù)數(shù)組,從而可以獲取傳遞給函數(shù)的每一個參數(shù)。
如下代碼:
function howManyArgs(){ alert(arguments.length); } howManyArgs("String",45); //2 howManyArgs(); //0 howManyArgs(12); //1
從上面的代碼可以看出來,定義函數(shù)時沒有給函數(shù)指定參數(shù)名字,而調(diào)用時依然可以傳遞進(jìn)去任何數(shù)量和類型的參數(shù),因此在js函數(shù)中:命名的參數(shù)只是提供便利,但不是必須的。理解這點(diǎn)很重要。
不完美的重載:::::::::::::::::
既然可以用arguments.length判斷傳入?yún)?shù)的個數(shù),那么js函數(shù)也可以實(shí)現(xiàn)不完美的重載。
如下代碼:
function doAdd(){ if(arguments.length == 1){ alert(arguments[0] + 10); } if(arguments.length == 2){ alert(arguments[0] + arguments[1]); } } doAdd(10); //20 doAdd(30,20); //50
arguments[i]和對應(yīng)命名參數(shù)的關(guān)系:::::::::::::::::
看如下代碼:
function doAdd(num1,num2){ arguments[1] = 10; //重寫第二個參數(shù) alert(arguments[0] + num2); }
arguments對象中的值會自動反映到對應(yīng)的命名參數(shù),但是讀取這兩個值不會訪問相同的內(nèi)存空間,
修改命名參數(shù)并不會改變arguments中對應(yīng)的值
arguments對象長度是由調(diào)用函數(shù)時傳入的參數(shù)個數(shù)決定的,不是由定義函數(shù)時的命名參數(shù)的個數(shù)決定的。
js中所有的函數(shù)都是按值傳遞的。
在向參數(shù)傳遞基本類型時,被傳遞的值會被復(fù)制給一個局部變量。
在向參數(shù)傳遞引用類型的值時,會把這個值在內(nèi)存中的地址復(fù)制給一個局部變量,因此這個局部變量的變化會反映在函數(shù)的外部。
來看幾個例子:
function addTen(num){ num += 10; return num; } var count = 20; var result = addTen(count); alert(count); //20,沒有變化 alert(result); //30
count傳遞給參數(shù)num,函數(shù)內(nèi)部num做了修改,但是沒有反映到count上。
function setName(obj){ obj.name = "Jack"; } var person = new Object(); setName(person); alert(person.name); //Jack
這個例子很容易讓人覺得,引用類型做為函數(shù)參數(shù)傳遞是按引用傳遞的,因?yàn)榫植康男薷模簅bj.name = "Jack",反映在了全局的作用域上:person.name,事實(shí)上并不是如此。
事實(shí)上:我們創(chuàng)建了一個對象,并把它保存在person變量中,然后把person當(dāng)做參數(shù)傳遞到setName()函數(shù)中復(fù)制給了obj,在這個函數(shù)內(nèi)部obj和person引用的是同一個對象。
再看一個例子:
function setName(obj){ obj.name = "Jack"; obj = new Object(); obj.name = "Rose"; } var person = new Object(); setName(person); alert(person.name); //Jack
這個例子中在setName()函數(shù)中,為obj重新定義了一個對象,另一行代碼為該對象定義了一個帶有不同值的name屬性。如果person傳遞給函數(shù)setName()之后是按引用傳遞的,那么對obj.name的修改就會反映到person.name上,事實(shí)上person.name依然是Jack。
當(dāng)在函數(shù)內(nèi)部重寫obj時,這個變量的引用就是一個局部變量了,這個局部變量在函數(shù)執(zhí)行完畢后立即銷毀。
定義什么的太多了就不寫了,直接上代碼
var color = "blue"; function changeColor(){ var anotherColor = "red"; function swapColors(){ var tempColor = anotherColor; anotherColor = color; color = tempColor; //這里可以訪問 color,anotherColor 和tempColor } swapColor(); //這里可以訪問color, anotherColor } changeColor(); //這里只能訪問color
上面代碼中有三個執(zhí)行環(huán)境:全局環(huán)境、changeColor()的局部、和swapColors()的局部環(huán)境。
全局環(huán)境中有一個color變量和changeColor()函數(shù)。
changeColor()的局部環(huán)境中有一個名為anotherColor的變量和一個swapColors()的函數(shù),但是它也可以訪問全局環(huán)境中的變量color
swapColors()局部環(huán)境中有一個變量tempColor,只能在這個環(huán)境中訪問到。
無論是全局環(huán)境還是changeColor()的局部環(huán)境都無權(quán)訪問tempColor,在swapColors()內(nèi)部可以訪問其他兩個環(huán)境中的所有變量,因?yàn)槟莾蓚€環(huán)境是它的父執(zhí)行環(huán)境。
總結(jié):內(nèi)部環(huán)境可以通過作用域鏈訪問所有的外部環(huán)境,但外部環(huán)境不能訪問內(nèi)部環(huán)境中的任何變量和函數(shù),每個環(huán)境內(nèi)部沒有這個變量或者函數(shù)時,都可以向上搜索變量和函數(shù)名,直到找到為止。
沒有塊級作用域java等語言話括號括起來的代碼塊都有自己的作用域,但是js中總有例外,看下面代碼:
if(true){ var color = "blue"; } alert(color); //blue
這里是在if語句中定義了一個變量color,和作用域函數(shù)里面定義變量的例子不同,在if語句中的變量聲明將添加到當(dāng)前的執(zhí)行環(huán)境中,看下面for循環(huán)的例子:
for(var i = 0; i<10; i++){ doSomething(i); } alert(i); //10
對于js,由for語句創(chuàng)建的變量i即使在for循環(huán)執(zhí)行結(jié)束后,也依舊會存在于循環(huán)外部的執(zhí)行環(huán)境。
4.匿名函數(shù)看下面例子:
window.onload = function(){ alert("Hello World"); }; var person = { callName: function(){ alert("My name is Jack"); } }; person.callName(); setTimeout( function(){alert("Hello World");}, 500);
1.首先,為load事件創(chuàng)建了一個函數(shù)做為事件處理程序,不會直接調(diào)用這個函數(shù),而是在頁面加載時自動調(diào)用,所以沒必要為這個函數(shù)命名,像這樣:
function sayHello(){alert("Hello World");}; window.onload = sayHello;
2.聲明了一個匿名函數(shù),做為person對象的一個屬性callName,可以通過該屬性來調(diào)用這個方法:
如:person.callName();
3.將匿名函數(shù)做為回調(diào)函數(shù)傳遞給另外一個函數(shù),代碼中將匿名函數(shù)做為一個參數(shù)傳遞給window對象的setTimeout()方法,該方法將在半秒后被調(diào)用。
-------------------------------------------------------end--------------------------------------------------------
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/79711.html
摘要:前言最近在學(xué)前幾天看到兩道題剛開始看懵懵懂懂這幾天通過各種查資料慢慢的理解頓悟了對匿名函數(shù)閉包立即執(zhí)行函數(shù)的理解也更深了一點(diǎn)在此分享給大家我的理解與總結(jié)希望能幫助大家理解因?yàn)檫@篇文章是我用心總結(jié)的查閱了很多的資料所以總結(jié)的比較細(xì)篇幅較長如果 前言 最近在學(xué)JS,前幾天看到兩道題,剛開始看懵懵懂懂,這幾天通過各種查資料,慢慢的理解,頓悟了,對匿名函數(shù),閉包,立即執(zhí)行函數(shù)的理解也更深了一點(diǎn)...
摘要:執(zhí)行返回的內(nèi)部函數(shù),依然能訪問變量輸出閉包中的作用域鏈理解作用域鏈對理解閉包也很有幫助。早期的版本里采用是計(jì)數(shù)的垃圾回收機(jī)制,閉包導(dǎo)致內(nèi)存泄露的一個原因就是這個算法的一個缺陷。 關(guān)于閉包,我翻了幾遍書,看了幾遍視頻,查了一些資料,可是還是迷迷糊糊的,干脆自己動手來個總結(jié)吧 !歡迎指正... (~ o ~)~zZ 1. 什么是閉包? 來看一些關(guān)于閉包的定義: 閉包是指有權(quán)...
摘要:閉包引起的內(nèi)存泄漏總結(jié)從理論的角度將由于作用域鏈的特性中所有函數(shù)都是閉包但是從應(yīng)用的角度來說只有當(dāng)函數(shù)以返回值返回或者當(dāng)函數(shù)以參數(shù)形式使用或者當(dāng)函數(shù)中自由變量在函數(shù)外被引用時才能成為明確意義上的閉包。 文章同步到github js的閉包概念幾乎是任何面試官都會問的問題,最近把閉包這塊的概念梳理了一下,記錄成以下文章。 什么是閉包 我先列出一些官方及經(jīng)典書籍等書中給出的概念,這些概念雖然...
摘要:閉包的學(xué)術(shù)定義先來參考下各大權(quán)威對閉包的學(xué)術(shù)定義百科閉包,又稱詞法閉包或函數(shù)閉包,是引用了自由變量的函數(shù)。所以,有另一種說法認(rèn)為閉包是由函數(shù)和與其相關(guān)的引用環(huán)境組合而成的實(shí)體。 前言 上一章講解了閉包的底層實(shí)現(xiàn)細(xì)節(jié),我想大家對閉包的概念應(yīng)該也有了個大概印象,但是真要用簡短的幾句話來說清楚,這還真不是件容易的事。這里我們就來總結(jié)提煉下閉包的概念,以應(yīng)付那些非專人士的心血來潮。 閉包的學(xué)術(shù)...
摘要:一般來講,函數(shù)執(zhí)行完畢后,局部活動對象就會被銷毀,內(nèi)存中僅保存全局作用域,但是閉包的情況有所不同理解閉包的前提先理解另外兩個內(nèi)容作用域鏈垃圾回收作用域鏈當(dāng)代碼在執(zhí)行過程中,會創(chuàng)建變量對象的一個作用域鏈。 閉包是javascript語言的一個難點(diǎn),也是它的特色,很多高級應(yīng)用都要依靠閉包來實(shí)現(xiàn)。個人的理解是:函數(shù)中嵌套函數(shù)。 閉包的定義及其優(yōu)缺點(diǎn) 閉包是指有權(quán)訪問另一個函數(shù)作用域中的變量的...
閱讀 2490·2021-10-19 11:45
閱讀 2473·2021-09-30 09:56
閱讀 1439·2021-09-30 09:47
閱讀 594·2019-08-30 15:53
閱讀 1838·2019-08-30 15:44
閱讀 587·2019-08-30 12:52
閱讀 1089·2019-08-30 11:16
閱讀 1613·2019-08-29 16:36