淺談JavaScript的對(duì)象類型之function
目錄
- 一、Function
- 定義函數(shù)
- 默認(rèn)參數(shù)
- 匿名函數(shù)
- 二、函數(shù)是對(duì)象
- 三、函數(shù)作用域
- 四、閉包
- 五、let、var與作用域
一、Function
定義函數(shù)
function 函數(shù)名(參數(shù)) { // 函數(shù)體 return 結(jié)果; }
例如:
function add(a, b) { return a + b; }
調(diào)用函數(shù)
函數(shù)名(實(shí)參);
例如:
add(1, 2); // 返回 3
js中的函數(shù)調(diào)用特點(diǎn),對(duì)參數(shù)的類型和個(gè)數(shù)都沒有限制,例如:
add("a", "b"); // 返回 ab add(4, 5, 6); // 返回 9, 第三個(gè)參數(shù)沒有被用到, 不會(huì)報(bào)錯(cuò) add(1); // 返回 NaN, 這時(shí) b 沒有定義是 undefined, undefined 做數(shù)學(xué)運(yùn)算結(jié)果就是 NaN
默認(rèn)參數(shù)
java中(spring)要實(shí)現(xiàn)默認(rèn)參數(shù)的效果
@RestController public class MyController { @RequestMapping("/page") @ResponseBody public void page( @RequestParam(defaultValue="1") int page, @RequestParam(defaultValue="10") int size ){ // ... } }
js實(shí)現(xiàn)的效果
function pagination(page = 1, size = 10) { console.log(page, size); }
匿名函數(shù)
語(yǔ)法:
(function (參數(shù)) { // 函數(shù)體 return 結(jié)果; })
例如:
(function(a,b){ return a + b; })
第一種場(chǎng)景:定義完畢后立刻調(diào)用
(function(a,b){ return a + b; })(1,2)
第二種場(chǎng)景:作為其他對(duì)象的方法,例如:
頁(yè)面有元素:
<p id="p1">點(diǎn)我啊</p>
此元素有一個(gè)onclick方法,會(huì)在鼠標(biāo)單擊這個(gè)元素后被執(zhí)行,onclick方法剛開始是null,需要賦值后才能使用
document.getElementById("p1").onclick = (function(){ console.log("鼠標(biāo)單擊了..."); });
箭頭函數(shù)
(參數(shù)) => { // 函數(shù)體 return 結(jié)果; }
- 如果沒有參數(shù),() 還是要保留
- 如果只有一個(gè)參數(shù),() 可以省略
- 如果函數(shù)體內(nèi)只有一行代碼,{} 可以省略
- 如果這一行代碼就是結(jié)果,return 可以省略
例如:
document.getElementById("p1").onclick = () => console.log("aa");
二、函數(shù)是對(duì)象
1、可以參與賦值,例如,匿名函數(shù)也能參與賦值
function abc() { console.log("bb"); } document.getElementById("p1").onclick = abc;
2、有屬性、有方法,執(zhí)行console.dir(abc),輸出結(jié)果如下:
? abc() arguments: null caller: null length: 0 name: "abc" ?prototype: {constructor: ?} [[FunctionLocation]]: VM1962:1 ?[[Prototype]]: ? () ?[[Scopes]]: Scopes[1]
其中帶有 f 標(biāo)記的是方法,不帶的是屬性
帶有 ? 符號(hào)的可以繼續(xù)展開,限于篇幅省略了
帶有
[[ ]]
的是內(nèi)置屬性,不能訪問,只能查看相對(duì)重要的是
[[Prototype]]
和[[Scopes]]
會(huì)在后面繼承和作用域時(shí)講到
3、可作為方法參數(shù)
function a() { console.log("a") } function b(fn) { // fn 將來(lái)可以是一個(gè)函數(shù)對(duì)象 console.log("b") fn(); // 調(diào)用函數(shù)對(duì)象 } b(a)
4、可作為方法返回值
function c() { console.log("c"); function d() { console.log("d"); } return d; } c()()
三、函數(shù)作用域
函數(shù)可以嵌套(js代碼很常見,只是嵌套形式很多時(shí)匿名函數(shù),箭頭函數(shù))
function a() { function b() { } }
例如:
function c() { var z = 30; } var x = 10; function a() { var y = 20; function b() { // 看這里 console.log(x, y); } b(); } a();
- 以函數(shù)為分界線劃定作用域,所有函數(shù)之外是全局作用域
- 查找變量時(shí),由內(nèi)向外查找
- 在內(nèi)層作用域找到變量,就會(huì)停止查找,不會(huì)再找外層
- 所有作用域都找不到變量,報(bào)錯(cuò)
- 作用域本質(zhì)上是函數(shù)對(duì)象的屬性,可以通過 console.dir 來(lái)查看調(diào)試
四、閉包
var x = 10; function a() { var y = 20; function b() { console.log(x,y); } return b; } a()(); // 在外面執(zhí)行了 b
- 函數(shù)定義時(shí),它的作用域已經(jīng)確定好了,因此無(wú)論函數(shù)將來(lái)去了哪,都能從它的作用域中找到當(dāng)時(shí)那些變量
- 別被概念忽悠了,閉包就是指函數(shù)能夠訪問自己的作用域中變量
五、let、var與作用域
如果函數(shù)外層引用的是let變量,那么外層普遍的{}也會(huì)作為作用于邊界,最外層的let也占一個(gè)script作用域
let x = 10; if(true) { let y = 20; function b() { console.log(x,y); } console.dir(b); }
如果函數(shù)外層引用的是var變量,外層普遍的{}不會(huì)視為邊界
var x = 10; if(true) { var y = 20; function b() { console.log(x,y); } console.dir(b); }
如果var變量出現(xiàn)了重名,則他倆會(huì)被視為同一作用域中的同一變量
var e = 10; if(true) { var e = 20; console.log(e); // 打印 20 } console.log(e); // 因?yàn)槭峭粋€(gè)變量,還是打印 20
如果是let,則視為兩個(gè)作用域中的兩個(gè)變量
let e = 10; if(true) { let e = 20; console.log(e); // 打印 20 } console.log(e); // 打印 10
要想里面的e和外面的e能區(qū)分開來(lái),最簡(jiǎn)單的辦法是改成let,或者用函數(shù)來(lái)界定作用域范圍
var e = 10; if(true) { function b() { var e = 20; console.log(e); } b(); } console.log(e);
到此這篇關(guān)于淺談JavaScript的對(duì)象類型之function的文章就介紹到這了,更多相關(guān)JavaScript 對(duì)象類型function內(nèi)容請(qǐng)搜索以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持!
相關(guān)文章:
