[JavaScript]JavaScript中的函數(1)

來源:互聯網
上載者:User

標籤:數組   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
  • window.Function
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)

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.