摘要:作用域鏈的用途,是為了保證對(duì)執(zhí)行環(huán)境有權(quán)訪問(wèn)的所有變量和函數(shù)的有序的訪問(wèn)。即全局作用域和局部作用域的變量的訪問(wèn)權(quán)限是由作用域鏈決定的。搜索過(guò)程始終從作用域鏈的前端開(kāi)始,然后逐級(jí)的向后回溯,直到找到標(biāo)識(shí)符如果找不到標(biāo)識(shí)符,通常會(huì)報(bào)錯(cuò)。
ECMAScript核心語(yǔ)法結(jié)構(gòu)之函數(shù)詳解 一、函數(shù)的概念
函數(shù)是一段可以反復(fù)調(diào)用的代碼塊。接受輸入的參數(shù),不同的參數(shù)會(huì)返回不同的值。
1.函數(shù)的定義ECMAScript中是使用function關(guān)鍵字來(lái)聲明,后面跟一組參數(shù)以及函數(shù)體。
1) 聲明函數(shù)
function sum (num1,num2){ return num1 + num2; } //可以先使用后定義。 解析器在執(zhí)行環(huán)境中加載數(shù)據(jù)時(shí),會(huì)率先讀取函數(shù)聲明。
2) 函數(shù)表達(dá)式:將一個(gè)匿名函數(shù)賦值給一個(gè)變量
var sum = function (num1,num2){ return num1 + num2; } //必須定義后使用(否則會(huì)報(bào)錯(cuò))。到解析器執(zhí)行到它所在的代碼行,才會(huì)真正被解析執(zhí)行
3) 構(gòu)造函數(shù)(幾乎不用)
var sum = new Funtion( "num1", "num2", "return num1 + num2" ) //等同于上面的聲明函數(shù)2.函數(shù)的調(diào)用(括號(hào)運(yùn)算符)
函數(shù)可以通過(guò)其函數(shù)名調(diào)用,后面還要加上一對(duì)圓括號(hào)和參數(shù)(如果有多個(gè)參數(shù),用逗號(hào)隔開(kāi))
function sum(num1, num2) { return num1 + num2; } sum(1, 1) //23.函數(shù)的參數(shù)
1.什么是參數(shù)
函數(shù)運(yùn)行的時(shí)候,有時(shí)需要提供外部數(shù)據(jù),不同的外部數(shù)據(jù)會(huì)得到不同的結(jié)果,這種外部數(shù)據(jù)就叫參數(shù)。
function sum (num1,num2){ return num1 + num2; } sum(1,2); //3 sum(1) //NAN num2 undefind;
2.參數(shù)的傳遞方式 - 按值傳遞
(1) 基本類型值的傳遞如同基本類型變量的復(fù)制一樣。
(2) 引用類型值的傳遞則如同引用類型變量的復(fù)制一樣(將這個(gè)值在內(nèi)存中的地址復(fù)制給了一個(gè)局部變量,因此這個(gè)局部變量的變化就會(huì)反在函數(shù)的外部)
//基本類型的傳遞 function addTen(num) { num += 10; return num; } var count = 20; var result = addTen(count); alert(count); //20,沒(méi)有變化 alert(result); //30 //引用類型的傳遞 var person = new Object(); function setName(obj) { alert(person.name); //undefined obj.name = "Nicholas"; alert(person.name) //"Nicholas" } setName(person); alert(person.name); //"Nicholas"
3.arguments對(duì)象(讀取函數(shù)體內(nèi)部所有參數(shù))
arguments對(duì)象是一個(gè)類數(shù)組(有l(wèi)ength屬性,但沒(méi)有數(shù)組的任何方法)
可以編寫無(wú)需指定參數(shù)個(gè)數(shù)的函數(shù)
var sum=function(){ var sum=0; for(var i=0;i4. 函數(shù)的返回值(return) 函數(shù)可以通過(guò)return語(yǔ)句跟要返回的值來(lái)實(shí)現(xiàn)返回值。函數(shù)在執(zhí)行完return語(yǔ)句之后停止并立即退出。因此,在return語(yǔ)句之后的任何代碼永遠(yuǎn)都會(huì)回執(zhí)行。
function sum(num1, num2) { return num1 + num2; alert("Hello world") //永遠(yuǎn)不會(huì)執(zhí)行 }return語(yǔ)句不是必須的,如果沒(méi)有的話,該函數(shù)就不會(huì)返回任何值,或者說(shuō)返undefined;
function sum(num1, num2) { alert (num1 + num2) } //undefined5.函數(shù)沒(méi)有重載(函數(shù)的重復(fù)聲明)函數(shù)重載:在其他語(yǔ)言(Java)中可以為一個(gè)函數(shù)體編寫兩個(gè)定義,只要定義的簽名(接收的參數(shù)的類型和參數(shù)不同即可))
在ECMASctipt中如果同一個(gè)函數(shù)被多次聲明,后面的聲明就會(huì)覆蓋前面的聲明。function addSomeNumber(num){ return num + 100; } function addSomeNumber(num) { return num + 200; } var result = addSomeNumber(100); //3006.函數(shù)的屬性和方法(1) name屬性(返回name的名字)
function sum (){} sum.name // "sum"(2) length 屬性
函數(shù)的length屬性返回函數(shù)預(yù)期傳入的參數(shù)個(gè)數(shù),即函數(shù)定義之中的參數(shù)個(gè)數(shù)。
function f(a,b){ return f.length } f(1,2,3,4) //2 ==> length屬性就是定義是的參數(shù)個(gè)數(shù)。不管調(diào)用時(shí)傳入了多少參數(shù),length屬性的始終等于2(3)apply()和call()
每個(gè)函數(shù)都包含兩個(gè)非繼承而來(lái)的方法:apply()和和call()。這兩個(gè)方法的用途都是在特定的作用域中調(diào)用函數(shù),實(shí)際上等于設(shè)置函數(shù)體內(nèi)this對(duì)象的值。
apply()方法接收兩個(gè)參數(shù),一個(gè)是在其運(yùn)行函數(shù)體內(nèi)的作用域,另一個(gè)是參數(shù)數(shù)組。其中第二個(gè)參數(shù)是數(shù)組或者arguments對(duì)象。
call()方法接收兩個(gè)參數(shù),第一個(gè)參數(shù)是this值沒(méi)有變化,變化的是其余參數(shù)都是直接傳遞給函數(shù)(的參數(shù)必須逐個(gè)列舉出來(lái))1.傳參
function sum(num,num2){ return num1 + num2; } function callSum(){ return sum.call(this,num1,num2); } alert(callSum(10,10)); //202.擴(kuò)充函數(shù)賴以運(yùn)行的作用域 (改變this指向的值)
var color = "red"; var o = { color: "blue" } sayColor.call(); //red(默認(rèn)傳遞參數(shù)this) sayColor.call(this); //red sayColor.call(window); //red sayColor.call(o); //blue二、函數(shù)的作用域和作用域鏈 1.作用域(1)什么是作用域
作用域(scope)指的是變量存在的范圍。 在es5中的,Javascript只有兩種作用域:一種是全局作用域,變量在整個(gè)程序中一直存在,所有地方都可以讀取;另一種是函數(shù)作用域,變量只在函數(shù)內(nèi)部存在。(es6中又新增了塊級(jí)作用域)
全局作用域可以在代碼的任何地方都能被訪問(wèn)var color1 = "blue"; function colorFn (){ var color2 = "red"; color3 = "yellow"; console.log(color1); console.log(color2); console.log(color3); } colorFn(); console.log(color1); //"blue" console.log(color2); // error console.log(color3); //"yellow" //函數(shù)changeColor()的作用域鏈包含兩個(gè)對(duì)象:它自己的變量對(duì)象(定義著arguments對(duì)象)和全局的變量的對(duì)象2.作用域鏈1.當(dāng)代碼在一個(gè)執(zhí)行環(huán)境中執(zhí)行時(shí),就會(huì)創(chuàng)建一個(gè)作用域鏈。
2.作用域鏈的用途,是為了保證對(duì)執(zhí)行環(huán)境有權(quán)訪問(wèn)的所有變量和函數(shù)的有序的訪問(wèn)。即全局作用域和局部作用域的變量的訪問(wèn)權(quán)限是由作用域鏈決定的。
3.作用域鏈的是從當(dāng)前的執(zhí)行環(huán)境的變量對(duì)象在這個(gè)環(huán)境中可以訪問(wèn)的變量對(duì)象開(kāi)始,到全局執(zhí)行環(huán)境的變量對(duì)象結(jié)束。(在這個(gè)環(huán)境中可以訪問(wèn)的變量)
4.內(nèi)部環(huán)境可以通過(guò)作用域鏈訪問(wèn)所有外部環(huán)境,但是外部環(huán)境不能訪問(wèn)內(nèi)部環(huán)境中的任何變量和函數(shù)。
5.標(biāo)示符(變量、函數(shù)、屬性的名字,或者函數(shù)的參數(shù))的解析是沿著作用域鏈一級(jí)一級(jí)的搜索標(biāo)示符的過(guò)程。搜索過(guò)程始終從作用域鏈的前端開(kāi)始,然后逐級(jí)的向后回溯,直到找到標(biāo)識(shí)符(如果找不到標(biāo)識(shí)符,通常會(huì)報(bào)錯(cuò))。
//在局部作用域中定義的變量可以在局部環(huán)境中與全局變量中互換使用 var color = "blue"; function changeColor(){ var anotherColor = "red"; function swapColors(){ var tempColor = anotherColor; anotherColor = color; color = tempColor; //這里可以訪問(wèn)color、anotherColor和tempColor } //這里可以訪問(wèn)color和anotherColor,但不能訪問(wèn)tempColor swapColors(); } //這個(gè)只能訪問(wèn)color; changeColor();三、函數(shù)的其他知識(shí)點(diǎn) 1.閉包函數(shù)(1) 什么是閉包函數(shù)
閉包函數(shù)是指有權(quán)訪問(wèn)另一個(gè)函數(shù)作用域中的變量的函數(shù)
(2) 創(chuàng)建閉包的常見(jiàn)方式,就是在一個(gè)函數(shù)內(nèi)部創(chuàng)建另一個(gè)函數(shù)//在函數(shù)內(nèi)部可以讀取函數(shù)外部的變量 var localVal = 30; function outer(){ return localVal; } outer();//30 //在函數(shù)外部自然無(wú)法讀取函數(shù)內(nèi)的局部變量 function outer(){ var localVal = 30; } alert(localVal);//error //通過(guò)閉包函數(shù)來(lái)讀取讀取outer函數(shù)內(nèi)部的變量 function outer(){ var localVal = 30; function inner(){ alert(localVal); } return inner; } var func = outer(); func();//30(3) 閉包的優(yōu)缺點(diǎn)
1) 使用閉包的好處是不會(huì)污染全局環(huán)境,方便進(jìn)行模塊化開(kāi)發(fā),減少形參個(gè)數(shù),延長(zhǎng)了形參的生命周期 2) 閉包會(huì)把函數(shù)中變量的值保存下來(lái),供其他函數(shù)使用,這些變量會(huì)一直保存在內(nèi)存當(dāng)中占用大量的內(nèi)存,使用不當(dāng)會(huì)造成內(nèi)存泄漏2.回調(diào)函數(shù)(1) 什么是回調(diào)函數(shù)(作為值的函數(shù))
回調(diào)函數(shù)也被稱作高階函數(shù),是一個(gè)被作為參數(shù)傳遞給另一個(gè)函數(shù)的函數(shù)。 function someFunction(someNum,callback){ return callback(someNum); } function add10(){ return num + 10; } someFunction()(2) 應(yīng)用場(chǎng)景實(shí)例:
1.數(shù)組中的一些方法 sort()、reverse()、forEach()、filter()等 var friends = ["Mike", "Stacy", "Andy", "Rick"]; friends.forEach(function (eachName, index){ console.log(index + 1 + ". " + eachName); // 1. Mike, 2. Stacy, 3. Andy, 4. Rick }); 2.事件的綁定 //原生綁定事件 document.body.addEventListener("cilck",function(){ alert("body Clicked"); }); //jq $("#btn_1").click(function() { alert("Btn 1 Clicked"); }); 3.ajax的請(qǐng)求 function getAjax (options, callback) { var xhr = new XMLHttpRequest(); xhr.open("get", options.url); xhr.onreadystatechange = function(){ if(xhr.readyState == 4){ if(xhr.status == 200){ callback && callback(xhr.responseText); } } }; xhr.send(); }3.遞歸函數(shù)1.什么是遞歸函數(shù)
遞歸函數(shù)是一個(gè)在函數(shù)通過(guò)名字調(diào)用自身的情況下構(gòu)成的。遞歸函數(shù)必須要有邊界條件function factorial(num){ if(num <= 1){ return 1 }else { return num * factorial(num - 1); } }2.arguments.calls()是一個(gè)指向正在執(zhí)行的函數(shù)指針 (嚴(yán)格模式下不支持)
//當(dāng)函數(shù)名發(fā)生改變時(shí)會(huì)導(dǎo)致代碼出錯(cuò)var anotherFactorial = factorial; factorial = null; alert(anotherFactorial(4)); //出錯(cuò)! function factorial(num){ if(num == 1){ return 1; } else { return num * arguments.callee(num-1) } }3.嚴(yán)格和非嚴(yán)格都有效
var factorial = (function f (num){ if(num == 1){ return 1; } else { return f(num-1) } })4.自執(zhí)行函數(shù)(1)什么是執(zhí)行函數(shù)
立即執(zhí)行函數(shù),就是在定義的時(shí)候立即執(zhí)行的函數(shù),執(zhí)行完以后釋放,包括函數(shù)內(nèi)部的所有變量(執(zhí)行完畢,立即銷毀其作用域鏈)(2)立即執(zhí)行函數(shù)的寫法
1.常用寫法 (function(){ })(); 2.w3c建議方式 (function(){ }()); 3.錯(cuò)誤寫法 function(){ }();函數(shù)聲明后面不能跟花括號(hào)(js會(huì)把function關(guān)鍵字當(dāng)做一個(gè)函數(shù)聲明的開(kāi)始)
函數(shù)表達(dá)式的后可以跟圓括號(hào)。要將函數(shù)聲明轉(zhuǎn)變成函數(shù)表達(dá)式
除圓括號(hào)外,!、+、-、=等運(yùn)算符,都將函數(shù)聲明轉(zhuǎn)換成函數(shù)表達(dá)式
!function(){}(); +function(){}(); -function(){}(); var fn=function(){}();(3) 模仿塊級(jí)作用域
function outputNumbers (count){ for(var i=0; i3.應(yīng)用場(chǎng)景
var list = document.getElementsByTagName("li"); for (var i = 0, len = list.length; i < len; i++) { (function(i){ //為了獲得不同的i值,使用立即調(diào)用函數(shù) list [i].onmouseover = function() { console.log("index is :" + i); } })(i); }
- 0
- 1
- 3
- 4
參考:
JavaScript高級(jí)程序設(shè)計(jì)(第3版)
https://wangdoc.com/javascrip...
https://www.cnblogs.com/caoru... JavaScript函數(shù)之作用域 / 作用鏈域 / 預(yù)解析
https://www.cnblogs.com/bucho... JavaScript中作用域和作用域鏈的簡(jiǎn)單理解(變量提升)
https://www.cnblogs.com/jingw... 閉包
https://www.cnblogs.com/langq...
https://www.cnblogs.com/mengf...
https://www.cnblogs.com/mafei... 立即執(zhí)行函數(shù)
https://baijiahao.baidu.com/s... 立即執(zhí)行函數(shù)
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/109328.html
摘要:上節(jié)我們講了同源策略,這節(jié)我們講講如何跨域。當(dāng)這些從的腳本執(zhí)行出錯(cuò),因?yàn)檫`背了同源策略為了保證用戶信息不被泄露,錯(cuò)誤信息不會(huì)顯示出來(lái),取而代之只會(huì)返回一個(gè)。 前端最基礎(chǔ)的就是 HTML+CSS+Javascript。掌握了這三門技術(shù)就算入門,但也僅僅是入門,現(xiàn)在前端開(kāi)發(fā)的定義已經(jīng)遠(yuǎn)遠(yuǎn)不止這些。前端小課堂(HTML/CSS/JS),本著提升技術(shù)水平,打牢基礎(chǔ)知識(shí)的中心思想,我們開(kāi)課啦(每...
摘要:前端最基礎(chǔ)的就是。前面我們已經(jīng)基本掌握常規(guī)的語(yǔ)法語(yǔ)義,以及基本的使用方法。等價(jià)于當(dāng)載入就緒執(zhí)行一個(gè)函數(shù)回調(diào)。返回一組匹配的元素。據(jù)提供的原始標(biāo)記字符串,動(dòng)態(tài)創(chuàng)建由對(duì)象包裝的元素。同時(shí)設(shè)置一系列的屬性事件等。 前端最基礎(chǔ)的就是 HTML+CSS+Javascript。掌握了這三門技術(shù)就算入門,但也僅僅是入門,現(xiàn)在前端開(kāi)發(fā)的定義已經(jīng)遠(yuǎn)遠(yuǎn)不止這些。前端小課堂(HTML/CSS/JS),本著提...
摘要:前端最基礎(chǔ)的就是。前面我們已經(jīng)基本掌握常規(guī)的語(yǔ)法語(yǔ)義,以及基本的使用方法。等價(jià)于當(dāng)載入就緒執(zhí)行一個(gè)函數(shù)回調(diào)。返回一組匹配的元素。據(jù)提供的原始標(biāo)記字符串,動(dòng)態(tài)創(chuàng)建由對(duì)象包裝的元素。同時(shí)設(shè)置一系列的屬性事件等。 前端最基礎(chǔ)的就是 HTML+CSS+Javascript。掌握了這三門技術(shù)就算入門,但也僅僅是入門,現(xiàn)在前端開(kāi)發(fā)的定義已經(jīng)遠(yuǎn)遠(yuǎn)不止這些。前端小課堂(HTML/CSS/JS),本著提...
摘要:同源策略是什么同源策略是瀏覽器的一個(gè)安全功能,不同源的數(shù)據(jù)禁止訪問(wèn)。或許你可以說(shuō)驗(yàn)證,在瀏覽器沒(méi)有同源策略的情況下這些都可以繞過(guò)去。總結(jié)同源策略是蠻好的,防御了大部分的攻擊。 前端最基礎(chǔ)的就是 HTML+CSS+Javascript。掌握了這三門技術(shù)就算入門,但也僅僅是入門,現(xiàn)在前端開(kāi)發(fā)的定義已經(jīng)遠(yuǎn)遠(yuǎn)不止這些。前端小課堂(HTML/CSS/JS),本著提升技術(shù)水平,打牢基礎(chǔ)知識(shí)的中心思...
摘要:前端最基礎(chǔ)的就是。幫助從舊的事件方法轉(zhuǎn)換,和。方法移除用綁定的事件處理程序。特定的事件處理程序可以被移除元素上提供事件名稱,命名空間,處理函數(shù)。用于過(guò)濾器的觸發(fā)事件的選擇器元素的后代。事件觸發(fā)模擬觸發(fā)原生使用觸發(fā)。 前端最基礎(chǔ)的就是 HTML+CSS+Javascript。掌握了這三門技術(shù)就算入門,但也僅僅是入門,現(xiàn)在前端開(kāi)發(fā)的定義已經(jīng)遠(yuǎn)遠(yuǎn)不止這些。前端小課堂(HTML/CSS/JS)...
閱讀 748·2021-10-14 09:43
閱讀 2072·2021-09-30 09:48
閱讀 3440·2021-09-08 09:45
閱讀 1089·2021-09-02 15:41
閱讀 1878·2021-08-26 14:15
閱讀 770·2021-08-03 14:04
閱讀 2972·2019-08-30 15:56
閱讀 3071·2019-08-30 15:52