標籤:數組 turn pre function 學習過程 cal name 閉包 key
關於JavaScript中函數的學習:
MDN
阮一峰老師的教程
關於函數的定義:
阮一峰老師:函數是一段可以反覆調用的代碼塊。函數還能接受輸入的參數,不同的參數會返回不同的值。
MDN:Function 建構函式 建立一個新的Function對象。 在 JavaScript 中, 每個函數實際上都是一個Function對象。
函數的聲明方式和name
函數的聲明方式有目前來說有5種,每一個函數都有他的一個name屬性(包括匿名函數),要注意。
function fn(x,y) { console.log(x + y)}fn.name //"fn"
var fnf = function(x,y){ console.log(x + y)}f.name //"f"
var fnfn = function f(x,y) { console.log(x + y)}fn.name //"f"f.name //f is not defined
var f = new Function(‘x‘,‘y‘,‘return x+y‘)f.name // "anonymous"
var fn = (x,y) => {return x + y}f.name //"fn"
現在最常用的就是具名函數和箭頭函數。
函數的調用和call()
在聲明了一個函數之後,我們就可以調用這個函數了。
但是,我們在調用一個函數的時候,究竟發生了什麼,搞清楚其中的機制,可以協助我們更深入地瞭解函數。
現梳理一下我的關於函數調用的思路:
首先我們聲明了一個函數:
var fn = function(x,y){ retrun x + y}
因為Function也是屬於一種對象,所以這個變數就有了一個地址A,這個地址A就指向堆記憶體中的對象B,對象B中就存放著我們的函數參數與函數體。
:
在這個對象B中的__proto__指向了Function.prototype,在Function.prototype中有一個特殊的call()屬性,這個方法對我們“調用函數”的這個動作來說至關重要。
每次調用函數時,其實就是使用這個call()屬性來執行函數體中的內容。
由於JavaScript這門語言的曆史遺留問題,fn.call()才是函數真正的調用方法。
注意
fn(1,2)等價於fn.call(undefined,1,2)
fn(1,2)相當於一種文法糖,但是call()方法能讓學習者更好地理解關於函數中的this和arguments概念,所以建議在學習過程中函數調用使用call(),直到掌握this為止。
函數中的this和arguments
函數中的 this指的到底是什嗎?
先下結論:this指的就是call()中的第一個參數,第一個參數往後都是arguments。
對此,我的理解是,他指的是一種域,一種範圍(可適當理解為函數的範圍),結合call()來看的話就很清晰明了了。
且看,我們聲明了一個函數:
var fn = function(x,y){ console.log(‘x:‘+x,‘y:‘+y) console.log(this)}fn(1,2)fn.call(undefined,1,2)
兩者的運行結果都是:
兩者的this都是一個window全域對象,我們來轉變一下:
var a = 3var obj = { a: 4}var fn = function(x,y){ console.log(‘x:‘+x,‘y:‘+y) console.log(this.a)}fn(1,2)fn.call(obj,1,2)
運行結果如下:
我們可以看到,因為我們在代碼前面聲明了一個賦值為3的全域對象a,第一個fn的調用中的this沒有改變,依然是window全域對象,所以函數fn中的this.a找的是全域範圍中的a,也就是列印出了3。
我們還在代碼前面聲明了一個對象,其中包含了一個key a,key的值為 4,第二個fn調用的時候,我們把對象obj當成參數傳給了fn,這個對象 obj就變成了fn的 this!!所以代碼運行時,函數fn中的this.a找的就是對象obj中的a。
因為正常的函數調用fn()簡化了傳入this的一步,而fn.call()則需要把this作為參數傳入,所以使用call()來學習this 是有好處的。
注意
普通模式與strict 模式
在普通模式和strict 模式下,this表現會有所不同:
// strict 模式var fn = function(x,y){ ‘use strict‘ console.log(‘x:‘+x,‘y:‘+y) console.log(this)}fn.call(undefined,1,2)fn.call(1,1,2)
// 普通模式var fn = function(x,y){ console.log(‘x:‘+x,‘y:‘+y) console.log(this)}fn.call(undefined,1,2)fn.call(1,1,2)
在普通模式下,如果this是undefined,瀏覽器會自動把this變成Window;如果是其他的值,則會打出一個對象(比如說1,則會打出一個Number 1的對象);
strict 模式下,如果this是undefined,他就是undefined,如果是其他的值,則會打出這個值本身。
arguments
arguments指的就是函數的參數。
使用arguments可以打出一個偽數組,偽數組就是像數組,但是__proto__中沒有Array.prototype的對象。
// 普通模式var fn = function(x,y){ console.log(‘x:‘+x,‘y:‘+y) console.log(arguments)}fn.call(undefined,1,2)
下一篇博文會接著總結一下函數中的範圍和閉包。
[JavaScript]JavaScript中的函數(1)