嘍大家好,我是作者“未來”,本期分享的內容是Web前端系列課程,本系列總共29個階段,堅持學習3個月蛻變為Web前端高手哦!
志同道合的小伙伴跟我一起學習交流哦!
把一段相對獨立的具有特定功能的代碼塊封裝起來,形成一個獨立實體,就是函數,起個名字(函數名),在后續開發中可以反復調用。
函數的作用就是封裝一段代碼,將來可以重復使用。
例:通過函數求兩個數字的和。
特點:
函數聲明的時候,函數體并不會執行,只有當函數被調用的時候才會執行。
函數一般都用來干一件事情,需用使用動詞+名詞,表示做一件事情 `tellStory` `sayHello`等。
注意:
函數需要先定義,然后才能使用
函數名字:要遵循駝峰命名法。
函數一旦重名,后面的會把前面的函數覆蓋。
Ctrl +鼠標左鍵---->轉到定義。
一個函數最好就是一個功能。
調用函數的語法:
函數名();
特點:
函數體只有在調用的時候才會執行,調用需要()進行調用。
可以調用多次(重復使用)。
代碼示例:
在函數定義的時候,函數名字后面的小括號里的變量就是參數,目的是函數在調用的時候,對用戶傳進來的值操作。
形參:函數在定義的時候小括號里的變量叫形參。
實參:函數在調用的時候小括號里傳入的值叫實參,實參可以是變量也可以是值。
函數內部是一個封閉的環境,可以通過參數的方式,把外部的值傳遞給函數內部。
調用的時候,把實參1的值給形參1,把實參2的值給形參2……
當函數執行完的時候,并不是所有時候都要把結果打印。我們期望函數給我一些反饋(比如計算的結果返回進行后續的運算),這個時候可以讓函數返回一些東西。也就是返回值。函數通過return返回一個返回值。
在函數內部有return關鍵字,并且在關鍵字后面有內容,這個內容被返回了。
當函數調用之后,需要這個返回值,那么就定義變量接收即可。
返回值語法:
函數的調用結果就是返回值,因此我們可以直接對函數調用結果進行操作。
返回值詳解:
-如果一個函數中有return ,那么這個函數就有返回值。
-如果一個函數中沒有return,那么這個函數就沒有返回值。
-如果一個函數中沒有明確的返回值,那么調用的時候接收了,結果就是undefined
(沒有明確返回值:函數中沒有return,函數中有return,但是return后面沒有任何內容)。
-函數沒有返回值,但是在調用的時候接收了,那么結果就是undefined。
-變量聲明了,沒有賦值,結果也是undefined。
-如果一個函數有參數,有參數的函數。
-如果一個函數沒有參數,沒有參數的函數。
-形參的個數和實參的個數可以不一致。
-return 下面的代碼是不會執行的。
- 求1-100之間所有數的和
-求1-n之間所有的數字的和
- 求n-m之間所有數的和
- 圓的面積
-求三個數中的最大數
-判斷一個數是不是素數
-求兩個數字的差
-求一組數字中的最大值
-求一個數組中的最大值和最小值還有和
-通過函數實現數組反轉
-通過函數實現冒泡排序
- 求階乘
定義一個函數,如果不確定用戶是否傳入了參數,或者說不知道用戶傳了幾個參數,沒辦法計算,可以使用arguments。
JavaScript中,arguments對象是比較特別的一個對象,實際上是當前函數的一個內置屬性。也就是說所有函數都內置了一個arguments對象,arguments對象中存儲了傳遞的所有的實參。arguments是一個偽數組,因此可以進行遍歷。
求任意個數的和
?
看不懂的小伙伴不要氣餒,后續的分享中將持續解釋,只要你跟著我分享的課程從頭到尾去學習,每篇文章看三遍,一個月后,回過頭來看之前的文章就會感覺簡單極了。
本章已結束,下篇文章將分享《函數其它補充,作用域、預解析》小伙伴們不要錯過喲!
這里是云端源想IT,幫你輕松學IT”
嗨~ 今天的你過得還好嗎?
不必讓種種記憶永遠和自己同在
就讓它留在它所形成的地方吧
- 2024.05.13 -
JavaScript是一種基于原型的高級、解釋型編程語言,它是一門動態語言,常用于網頁交互和前后端開發。在JavaScript中,函數是一段可重復使用的代碼塊,它可以執行一個特定的任務。
函數的使用可以增加代碼的模塊性和重用性,使得代碼更加簡潔明了。本文將介紹如何在JavaScript中創建和使用函數。
簡單來說,函數就是一段可重復使用的代碼塊,它可以接收輸入參數,執行特定的操作,并返回結果。在JavaScript中,我們可以使用關鍵字function來定義一個函數。例如:
function add(a, b) {
return a + b;
}
這個簡單的函數接受兩個參數a和b,然后返回它們的和。
函數的作用:
函數實際上是對象,每個函數都是Function類型的實例,并且都與其他引用類型一樣具有屬性和方法,由于函數是對象,因此函數名實際上也是一個指向函數對象的指針,不會與某個函數綁定。
在JavaScript中,有多種方式可以用來創建函數,其中最常用的有以下幾種:
1、函數聲明(Function Declaration)
函數聲明是最常見的創建函數的方式,它使用function關鍵字,后跟函數名和參數列表,然后是函數體。
例如,我們可以創建一個名為greet的函數,該函數接收一個參數name,并打印出一條問候消息:
function greet(name) {
console.log("Hello, " + name + "!");
}
2、函數表達式(Function Expression)
函數表達式是將函數定義為一個表達式的值。它與函數聲明類似,但是沒有函數名。
例如,我們可以創建一個匿名函數,并將其賦值給一個變量greet:
var greet=function(name) {
console.log("Hello, " + name + "!");
};
3、箭頭函數(Arrow Function)
箭頭函數是ES6引入的新特性,它提供了一種更簡潔的方式來創建函數。箭頭函數使用=>符號,左側是參數列表,右側是函數體。
例如,我們可以創建一個箭頭函數,并將其賦值給一個變量greet:
var greet=(name)=> {
console.log("Hello, " + name + "!");
};
函數內部屬性只能在函數內部才能訪問。
arguments
arguments是一個類數組對象,包含著傳入函數中的所有參數。arguments主要用途是保存函數參數。
function foo(){
console.log(arguments) // [Arguments] { '0': 1, '1': 2, '2': 3, '3': 4 }
console.log(arguments[1]) // 2
}
// 當傳遞的實參個數超過形參的個數的時候不會報錯,所有的實參都會保存在arguments里
foo(1,2,3,4)
注意:arguments 中存的是實參,而不會存形參。
function foo(a,b=2,c=3){
console.log(arguments) // [Arguments] { '0': 1 }
console.log(b) //2
console.log(c) //3
}
//只傳了一個實參,那么arguments中就只有一個值
foo(1)
callee 屬性
arguments 對象有一個名為callee的屬性,該屬性是一個指針,指向擁有這個arguments對象的函數。
arguments.callee 實際上就是函數名。
// 遞歸求n的階乘
function factorial(n) {
if (n==1) {
return 1
}
return arguments.callee(n - 1) * n //arguments.callee 相當于函數名factorial
}
console.log(factorial(10));
length 屬性
arguments 對象的 length 屬性返回實參個數。
function foo(){
console.log(arguments.length) //5
}
foo(1,2,3,4,5)
創建了函數后,我們就可以在代碼中調用它來執行特定的任務。函數調用是通過函數名和括號內的參數列表來實現的。
例如,我們可以調用上面創建的greet函數:
greet("Alice"); // 輸出:Hello, Alice!
此外,JavaScript還支持以下高級功能:
1、默認參數:
可以為函數的參數設置默認值,當調用函數時未提供該參數時,將使用默認值。
function greet(name="World") {
console.log("Hello, " + name + "!");
}
greet(); // 輸出:Hello, World!
greet("Alice"); // 輸出:Hello, Alice!
2、回調函數:
可以將函數作為參數傳遞給其他函數,以便在特定時機執行
setTimeout(function() {
console.log("This message will be displayed after 1 second.");
}, 1000);
3、遞歸函數:
函數可以直接或間接地調用自身,以實現復雜的邏輯。
function factorial(n) {
if (n===0) {
return 1;
} else {
return n * factorial(n - 1);
}
}
console.log(factorial(5)); // 輸出:120
JavaScript函數的作用域分為全局作用域和局部作用域。
全局作用域:全局作用域中的變量是在任何函數之外聲明的,或者是使用var關鍵字在一個函數內部聲明但沒有使用let或const的變量。這些變量在整個程序中都是可用的。
局部作用域:局部作用域中的變量是在函數體內聲明的,包括使用let、const或var關鍵字聲明的變量。這些變量只在函數內部及其子函數中可用,函數外部無法訪問。
此外,JavaScript還有塊級作用域,由{}包圍的代碼塊也可以創建新的作用域,通常用于控制流語句(如if、for等)中。在塊級作用域中聲明的變量,在塊外部是不可見的。
1、什么是閉包
簡單講,閉包就是指有權訪問另一個函數作用域中的變量的函數。
閉包是一種特殊的對象。它由兩部分構成:函數以及創建該函數的環境。環境由閉包創建時在作用域中的任何局部變量組成。
2、閉包形成的條件
閉包的生成有三個必要條件:
這樣就形成了一個不會銷毀的函數空間。
下面例子中的 closure 就是一個閉包:
function func() {
var a=1, b=2;
function closure() {
return a + b;
}
return closure;
}
console.log(func()()); // 3
閉包的作用域鏈包含著它自己的作用域,以及包含它的函數的作用域和全局作用域。
在Javascript語言中,只有函數內部的子函數才能讀取局部變量,因此可以把閉包簡單理解成 " 定義在一個函數內部的函數 " 。
所以,在本質上,閉包就是將函數內部和函數外部連接起來的一座橋梁。
3、閉包的作用
閉包可以用在許多地方。它的最大用處有兩個,一個是可以讀取函數內部的變量,另一個就是讓這些變量的值始終保持在內存中。
function f1() {
var n=999;
nAdd=function () {
n +=1
}
function f2() {
console.log(n);
}
return f2;
}
var result=f1();
result(); // 999
nAdd();
result(); // 1000
在這段代碼中,result 實際上就是閉包 f2函數。它一共運行了兩次,第一次的值是999,第二次的值是1000。這證明了,函數f1中的局部變量n一直保存在內存中,并沒有在f1調用后被自動清除。
為什么會這樣呢?原因就在于f1是f2的父函數,而f2被賦給了一個全局變量,這導致f2始終在內存中,而f2的存在依賴于f1,因此f1也始終在內存中,不會在調用結束后,被垃圾回收機制(garbage collection)回收。
這段代碼中另一個值得注意的地方,就是"nAdd=function(){n+=1}"這一行,首先在nAdd前面沒有使用var關鍵字,因此nAdd是一個全局變量,而不是局部變量。
其次,nAdd的值是一個匿名函數(anonymous function),而這個匿名函數本身也是一個閉包,所以nAdd相當于是一個setter,可以在函數外部對函數內部的局部變量進行操作。
4、使用閉包的注意點
(1)由于閉包會使得函數中的變量都被保存在內存中,內存消耗很大,所以不能濫用閉包,否則會造成網頁的性能問題,在IE中可能導致內存泄露,這是IE的BUG。解決方法是,在退出函數之前,將不使用的局部變量全部刪除。
(2)閉包會在父函數外部改變父函數內部變量的值。所以,如果你把父函數當作對象(object)使用,把閉包當作它的公用方法(Public Method),把內部變量當作它的私有屬性(private value),這時一定要小心,不要隨便改變父函數內部變量的值。
多個子函數的scope都是同時指向父級,是完全共享的。因此當父級的變量對象被修改時,所有子函數都受到影響。
JavaScript函數的創建和使用是編程過程中的基本技能,掌握好函數的使用可以使代碼更加模塊化、簡潔和高效。它們不僅可以幫助我們將代碼模塊化、復用,還可以實現更復雜的邏輯和功能。
希望這篇文章能幫助你更好地理解和應用JavaScript函數,讓你的編程之旅更加精彩!
我們下期再見!
END
文案編輯|云端學長
文案配圖|云端學長
內容由:云端源想分享
數(Function)是被設計為執行特定任務的代碼塊。它在可以實現定制運算功能的同時,還帶有一個入口和一個出口。所謂的入口,就是函數所帶的各個參數,我們可以通過這個入口,把函數的參數值代入子程序,供計算機處理;所謂出口,就是指函數的函數值,在計算求得結果之后,由此口帶回給調用它的程序。
在程序設計中,常將一些常用的功能模塊編寫成函數,放在函數庫中供用戶選用。善于利用函數,可以減少重復編寫程序段的工作量。
本文介紹Javascript函數的幾種常用定義方式。掌握JS函數基本技術后,在統計數據處理過程中,我們將函數理解為某一統計對象(項目)所定制的方法。
導讀:
1、普通函數
I、基本語法
function 函數名稱(參數1, 參數2, 參數3) {
//要執行的代碼
return 返回值
}
JavaScript函數語法解析如下:
II、無參數函數
console.clear();
function test1() {
return "Hello World!";
}
//執行函數返回"Hello World!",并賦值給變量str
var str=test1();
console.log(str);
注:Console對象用于JavaScript調試,為了顯示Console.log輸出結果,通過按Control+Shift+i(PC平臺)來打開Console窗口
III、有參數函數
//計算任意兩個數的和
function oSum(x, y) {
return x+y;
}
var mySum=oSum(15, 85);
console.log(mySum); //100
IV、參數默認值設置
//求和函數中給兩個參數設置默認值
console.clear();
function oSum(x=50, y=50) {
return x+y;
}
var mySum=oSum(15, 55);
console.log(mySum); //70
mySum=oSum(15);
console.log(mySum); //65
mySum=oSum();
console.log(mySum); //100
V、參數為函數
console.clear();
function oSum(x, y) {return x+y;}
var mySum=oSum(oSum(45, 75), 100);
console.log(mySum); //220
VI、對象{}為參數 - 解構賦值默認值
console.clear();
function oSum({x=10, y=20}) {
return x+y;
}
console.log(oSum({})); //30,這里直接調用oSum()出錯
console.log(oSum({x:100})); //120
console.log(oSum({y:100})); //110
console.log(oSum({x:100,y:200})); //300
console.log(oSum({y:50,x:20})); //70
VII、對象{}為參數 - 雙重默認值
//代碼容錯更好
console.clear();
function oSum({x=10, y=20}={}) {
return x+y;
}
console.log(oSum()); //30
console.log(oSum({})); //30
console.log(oSum({x:100})); //120
console.log(oSum({y:100})); //110
console.log(oSum({x:100,y:200})); //300
console.log(oSum({y:50,x:20})); //70
2、函數arguments對象
在JavaScript中,參數在函數內部是以一個數組表示的,arguments是函數內部的一個專門用來存儲實參的數組對象。函數arguments的對象在函數運行時用于檢測和重新設置參數。
I、arguments.length - 函數參數數量
console.clear();
function fn(a,b,c){
console.log(arguments.length); //3
return a+b+c;
}
console.log(fn(1,2,3)); //6
II、arguments[] - 函數輸出和設置
console.clear();
function fn(a,b,c){
console.log(arguments[0]); //1
console.log(arguments[1]); //2
console.log(arguments[2]); //3
arguments[0]=5; //重新設置參數a=5
return a+b+c;
}
console.log(fn(1,2,3)); //10
III、arguments轉數組
arguments對象不是一個真正的數組 ,它類似于數組,但除了length屬性和索引元素之外沒有任何數組屬性。例如,它沒有pop方法。但是它可以被轉換為一個真正的數組,轉換為真實的數組后就可以使用完整的數組方法
console.clear();
function fn(a, b, c) {
var arr=Array.from(arguments); //進行轉數組操作
console.log(arr); //輸出數組
return a + b + c;
}
console.log(fn(1, 2, 3)); //6
3、匿名函數
匿名函數顧名思義指的是沒有名稱的函數,在實際開發中使用的頻率非常高,是學好JS編程的重點。
I、變量匿名函數
console.clear();
var fn=function fn(a,b,c=9) {
return a+b+c;
}
console.log(fn(1,2)); //12
console.log(fn(1,2,3)); //6
II、無名稱匿名函數
即在函數聲明時,在后面緊跟參數。JS語法解析此函數時,里面代碼立即執行。
console.clear();
console.log(function(a,b){return a+b;}(2,3));
console.clear();
//加括號執行無匿名函數(輸出"Hello Word!")
(function (){
console.log("Hello Word!");
})()
//加括號執行有匿名函數(輸出"Hello Word! lei.")
(function (str){
console.log("Hello Word!" +" "+ str +".");
})("lei")
注:函數代碼function(a,b){return a+b;}沒指定函數名稱,如果需要執行匿名函數,在匿名函數后面加上一個括號即可立即執行
III、事件綁定匿名函數
通常我們瀏覽網頁時會通過鼠標或鍵盤輸入信息,例如鼠標點擊某個按鈕稱“click點擊事件”、文本框內文字信息改變了稱“change事件”。總之,用戶所有的鼠標、鍵盤操作都稱為事件,都可以通過JS代碼來捕獲這些事件。
console.clear();
//通過id或取圖標對象
var logo=document.querySelector("#myLogo");
//給左上角“銀河統計”圖標增加點擊事件
logo.onclick=function(){
console.log("歡迎來到銀河統計工作室!");
}
logo.onmousemove=function(){
logo.style.cursor="pointer";
console.log("鼠標在圖像上面!");
}
logo.onmouseout=function(){
logo.style.cursor="default";
console.log("鼠標已經離開圖像!");
}
注:代碼中網頁圖像標記為<img id="myLogo" src="###"/>
IV、對象綁定匿名函數做為對象的方法
前面我們介紹JS對象時提到,事件是有屬性和方法組成的數據結構,事件的方法可以通過綁定匿名函數的方式建立。
console.clear();
var obj={
name:"Carolyn",
age:11,
fn:function(str){
return "My name is "+this.name+" Siyu"+". I'm "+this.age+" years old now.";
}
};
console.log(obj.fn("Siyu")); //My name is Carolyn Siyu. I'm 11 years old now.
注:這里定匿名函數為屬性的返回值
V、匿名函數做為回調函數(callback)
什么是同步,什么是異步?
同步指的是一次只能完成一件任務。如果有多個任務,就必須排隊,前面一個任務完成,再執行后面一個任務,以此類推。
異步指的是每一個任務有一個或多個回調函數(callback),前一個任務結束后,不是執行后一個任務,而是執行回調函數,后一個任務則是不等前一個任務結束就執行,所以程序的執行順序與任務的排列順序是不一致的、異步的。
JS是單線程的,它本身不可能是異步的,通過回調函數可以實現異步。JS中最基礎的異步是setTimeout和setInterval函數。
console.clear();
var interval=setInterval(function(){
console.log("回調函數,每間隔1秒鐘會被執行一次");
},1000);
//點擊銀河統計圖表停止setInterval計算器運行
var logo=document.querySelector("#myLogo");
logo.onclick=function(){
console.log("Stop!");
clearInterval(interval)
}
setTimeout(function() {
console.log("張三")
}, 1000 );
setTimeout(function() {
console.log("李四")
}, 2000 );
setTimeout(function() {
console.log("王五")
}, 3000 );
//jS最基礎的異步實現
function a() {
console.log("執行a函數");
setTimeout(function() {
console.log("執行a函數的延遲函數");
},2000);
}
function b() {
console.log("執行b函數");
}
a();
b();
VI、匿名函數做為返回值
console.clear();
function fn(){
return function(){
return "Carolin";
}
}
//調用匿名函數
console.log(fn()()); //Carolin
//或者
var box=fn();
console.log(box()); //Carolin
4、閉包和遞歸函數
假設,函數A內部聲明了個函數B,函數B引用了函數B之外的變量,并且函數A的返回值為函數B的引用,那么函數B就是閉包函數。
遞歸就是函數自己調用自己,當函數自己時,其自身為閉包函數,參數為域外變量。
console.clear();
function funA(arg1,arg2) {
var i=0; //funA作用域的變量
function funB(step) {
i=i + step; //訪問funB作用域外變量i
console.log(i)
}
return funB;
}
var allShowA=funA(2, 3); //調用的是funA arg1=2,arg2=3
allShowA(1);//調用的是funB step=1,輸出 1
allShowA(3);//調用的是funB setp=3,輸出 4
//累加
console.clear();
function f(num){
if(num<1) {
return 0;
} else {
return f(num-1)+num;
}
}
console.log(f(9)); //45
//階乘
console.clear();
function f(num){
if(num<1) {
return 1;
} else {
return f(num-1)*num;
}
}
console.log(f(4)); //24
//在對象中定義遞歸方法
var obj={
num : 5,
fac : function (x) {
if (x===1) {
return 1;
} else {
return x * obj.fac(x - 1);
}
}
};
console.log(obj.fac(5)) /120
//使用arguments.callee
function fact(num){
if (num<=1){
return 1;
}else{
return num*arguments.callee(num-1);
}
}
console.log(fact(4)); //24
5、Promise回調函數
Promise是ES6語言標準中提供的對象。Promise是異步編程的一種解決方案,比傳統的解決方案(回調函數和事件)更合理和更強大。
console.clear();
//基本用法,
var p=new Promise(function(resolve, reject){
setTimeout(function(){
resolve(console.log("done"));
}, 1000);
});
//做為對象返回
function timeout(ms) {
return new Promise((resolve, reject)=> {
setTimeout(resolve, ms, 'done');
});
}
timeout(1000).then((value)=> { //參數value='done'
console.log(value);
});
//完整使用方法
function promiseTest(){
let p=new Promise(function(resolve, reject){
setTimeout(function(){
var num=Math.random()*100; //生成1-100的隨機數
console.log('隨機數生成的值:',num)
if(num>=60){
resolve(num);
} else {
reject('數字太于60了即將執行失敗回調');
}
}, 2000);
})
return p
}
promiseTest().then(
function(data){ //data=num
console.log('resolved成功回調');
console.log('成功回調接受的值:',data);
}
)
.catch(function(reason, data){
console.log('catch到rejected失敗回調');
console.log('catch失敗執行回調拋出失敗原因:',reason);
});
注:Promise回調函數在網頁數據抓取時常常遇到
JavaScript是一種面向對象的編程語言,因此對象在JavaScript中扮演了很重要的角色。
Javascript函數是能完成某個常用功能的一小段代碼,而Javascript方法(method)是通過對象調用的Javascript函數。
JS中所有事物都是對象,對象是擁有屬性和方法的數據。但是,JS對象又是由函數創建的,JS函數本身也是對象。“方法是函數、對象是函數”,JS中函數的用途和含義有點繞口,需要大量練習和運用才能掌握。
*請認真填寫需求信息,我們會在24小時內與您取得聯系。