JS 里的函數(shù)

講函數(shù)前,先了解Function和function的區(qū)別。

  • function是關(guān)鍵字(if else var )function聲明一個(gè)函數(shù) function f(){}
    Function是全局對(duì)象 new Function('x','y','return x+y',) 或者 Function('x','y','return x+y')

聲明函數(shù)有兩種方法1.關(guān)鍵字聲明 2.new Function聲明
1.具名函數(shù) function f(){ return undefined} 2.匿名函數(shù) var f f = function(){} 這兩個(gè)屬于第一種
3.new Function('x','y','return x+y ') 這個(gè)屬于第二種(除非無(wú)聊或者想用字符串拼湊的時(shí)候才有這種)

函數(shù)的五種聲明方式

  1. function f(x,y){ return x+y }
  2. var f = function (x,y){ return x+y }
  3. var f = function x(x,y){ return x+y }
  4. var f = new Function('x','y','return x+y') // window.Function
  5. var f= (x,y) => { return x+y }//es6的箭頭函數(shù)
    var f = (x,y) => x+y //return和花括號(hào)一起省略
    var f = n => n*n //參數(shù)只有一個(gè)時(shí),參數(shù)的括號(hào)可以省略

name知識(shí)點(diǎn)

每個(gè)函數(shù)都有名字,但是比較雞肋,基本用不到

function f(){}  
f.name     //     f
var f2 = function(){}
f2.name    //    f2
var f3 = function f4(){}
f3.name    //    f4
f4.name    //    f4 is not defined
f5 = new Function('x','y','return x+y ')
f5.name    //    anonymous

函數(shù)是可以反復(fù)調(diào)用的代碼塊 調(diào)用函數(shù)英文是call

call

var f = {}
f.params = ['x','y']
f.functionBody = 'console.log("fff")'
f.call = function (){
    return window.eval(f.functionBody)
}
f.call()  //    fff

call

call其實(shí)就是函數(shù)的復(fù)雜寫(xiě)法 f(1,2) === f.call(undefined,1,2),實(shí)際參數(shù)從第二個(gè)開(kāi)始傳,undefined是this , 1,2是arguments
call的第一個(gè)參數(shù)可以用this得到,call后面的參數(shù)可以用arguments得到
f和的區(qū)別 f是函數(shù)體 f.call()指向這個(gè)對(duì)象的函數(shù)體
call

其中可以執(zhí)行代碼的對(duì)象就叫函數(shù)(我們寫(xiě)的代碼)

函數(shù)原型Function.prototype有三個(gè)重要的方法call apply bind,會(huì)重寫(xiě)toString方法覆蓋Object的toString方法

this

在普通模式下,如果this是undefined,瀏覽器會(huì)自動(dòng)把this變成window

  f = function (){
     console.log(this == = window)
  }
  f.call(undefined)  // true

如果是嚴(yán)格模式,給undefined打印出的就是undefined,

  f = function (){
     'use strict'
     console.log(this === window)
  }
  f.call(undefined)  //false

arguments

argument是偽數(shù)組,因?yàn)樗脑玩溕蠜](méi)有Array.prototype,或者 proto沒(méi)有指向Array.prototype
下面判斷

f = function(){
    arguments.push(4)
    console.log(arguments)
}
f.call(undefined,1,2,3)   

會(huì)報(bào)arguments.push is not a function的錯(cuò),所以是偽數(shù)組
很好判斷是不是偽數(shù)組,給push方法

call stack 調(diào)用棧

Stack Overflow 和中國(guó)的segment fault 這兩個(gè)網(wǎng)站的由來(lái)就是從棧溢出而來(lái)的

function sum(n){
    if(n==1){
        return 1
    }else{
        return n + sum.call(undefined, n-1)
    }
}
sum.call(undefined,9650)  //46566075

再大就棧溢出Maximum call stack size exceeded,所有棧的調(diào)用最多在9650左右,再多就棧溢出了

call stack

作用域

在使用變量的時(shí)候 ,怎么去找它的聲明 ,就找這個(gè)作用域里面的聲明,找不到找外面作用域的聲明,如果還找不到 。再往外面找,就近原則
聲明提升:變量提升,函數(shù)的聲明也提升,先提升在看代碼

f1里的console.log是什么

var a = 1
function f1(){
    f2.call()
    console.log(a)    //undefined
    var a = 2
    function f2(){
        var a = 3
        console.log(a)
    }
}
f1.call()
console.log(a)   
//3 
//undefined 
//1

變量提升改寫(xiě)代碼

var a = 1
function f1(){
    var a
    function f2(){
        var a
        a = 3
        console.log(a) // a定義再賦值在console.log前面,所以是3    }
    f2.call()
    console.log(a)  // a先定義,賦值在console.log下面,所以是undefined
    a = 2
}
f1.call()
console.log(a)

例2
f4打印的是什么

var a = 1
function f1(){
    console.log(a)
    var a = 2
    f4.call()
    
}
function f4(){
    console.log(a)     //1, f4的a 一定是f4的作用域或者它的父作用域  
}
f1.call()
console.log(a)

f1的a只在f1函數(shù)里有效,而f4的a 一定是f4的作用域或者它的父作用域 ,不用和上面的變量提升搞混

例3
????里的內(nèi)容有沒(méi)有可能是的a輸出的不是1

var a = 1
function f4(){
    console.log(a)
}
???????   //a =  2   不是立刻執(zhí)行就可能是2
f4.call()

作用域說(shuō)的是a是那個(gè)a,但并沒(méi)有說(shuō)a是哪個(gè)a的值,如果????里設(shè)置了延時(shí)代碼,那么a就不一定是1了

閉包

var a = 1
function f4(){
    console.log(a)
}

這就是閉包 如果一個(gè)函數(shù),使用了它范圍外的變量,那么(這個(gè)函數(shù)+這個(gè)變量)就叫做閉包

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • "use strict";function _classCallCheck(e,t){if(!(e instanc...
    久些閱讀 2,156評(píng)論 0 2
  • Lua 5.1 參考手冊(cè) by Roberto Ierusalimschy, Luiz Henrique de F...
    蘇黎九歌閱讀 14,264評(píng)論 0 38
  • 第2章 基本語(yǔ)法 2.1 概述 基本句法和變量 語(yǔ)句 JavaScript程序的執(zhí)行單位為行(line),也就是一...
    悟名先生閱讀 4,616評(píng)論 0 13
  • “青青,那個(gè)王冠軍好厲害,扣籃也,那么遠(yuǎn)”齊青青旁邊一個(gè)四眼妹搖晃著自己的肩膀喊道。 “哎呀,放開(kāi)我??刍@,扣籃那...
    給我顆煙閱讀 240評(píng)論 0 0
  • 常用的垃圾回收算法有如下四種:標(biāo)記-清除、復(fù)制、標(biāo)記-整理和分代收集。 標(biāo)記-清除算法 從算法的名稱(chēng)上可以看出,這...
    JavaQ閱讀 263評(píng)論 0 1

友情鏈接更多精彩內(nèi)容