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