引用類型之Function類型

對(duì)于面向?qū)ο缶幊痰恼Z(yǔ)言來(lái)說(shuō),對(duì)象是很重要的一個(gè)概念,而對(duì)于函數(shù)來(lái)說(shuō),每個(gè)函數(shù)實(shí)際上都是對(duì)象,每個(gè)函數(shù)都是Function類型的實(shí)例,而且與其他引用類型一樣具有屬性和方法。

函數(shù)聲明與函數(shù)表達(dá)式

通常有三種聲明函數(shù)的方法

  1. 使用函數(shù)聲明語(yǔ)法
function sum(num1, num2) {
return num1 + num2;
}

這也是最常用的方法

  1. 使用函數(shù)表達(dá)式定義函數(shù)
var sum = function (num1, num2) {
return num1 + num2;
};

可能會(huì)注意到function關(guān)鍵字后面沒(méi)有函數(shù)名,這是因?yàn)槭褂煤瘮?shù)表達(dá)式定義函數(shù)時(shí),通過(guò)變量sum就可以引用函數(shù)

  1. 使用Function構(gòu)造函數(shù)
var sum = new Function("num1", "num2", "return num1 + num2");

但是非常不推薦這種寫法,因?yàn)檫@種語(yǔ)法會(huì)導(dǎo)致解析兩次代碼(第一次解析ECMAScript代碼,第二次解析傳入構(gòu)造函數(shù)的參數(shù))從而影響性能

關(guān)于變量提升

對(duì)于1,2兩種聲明函數(shù)的方法有什么不同呢?看下面這個(gè)例子

// 使用函數(shù)聲明創(chuàng)建函數(shù)
console.log(sum(10,10));  //會(huì)打印出20
function sum(num1, num2) {
  return num1 + num2;
};

// 使用函數(shù)表達(dá)式創(chuàng)建函數(shù)
console.log(add(10,10)); //會(huì)報(bào)錯(cuò)
var add = function(num1, num2) {
  return num1 + num2;
};

實(shí)際上,解析器在執(zhí)行環(huán)境中加載數(shù)據(jù)時(shí),解析器會(huì)率先讀取函數(shù)聲明,并使其在執(zhí)行任何代碼之前可用,而至于函數(shù)表達(dá)式,則必須等到解析器執(zhí)行到它所在的代碼行才會(huì)真正被解釋執(zhí)行。

函數(shù)內(nèi)部屬性

在函數(shù)內(nèi)部,有兩個(gè)特殊的對(duì)象:argumentsthis

arguments是一個(gè)類數(shù)組對(duì)象,包含著傳入函數(shù)的所有參數(shù),之前在基礎(chǔ)算法的時(shí)候已經(jīng)講過(guò)。但是arguments還有一個(gè)名叫callee屬性,該屬性是一個(gè)指針,指向擁有arguments對(duì)象的函數(shù)。具體用法之前寫過(guò)了,看這里

另一個(gè)比較特殊的對(duì)象就是this了,關(guān)于this知乎上@方方老師這篇文章講的特別好

函數(shù)的屬性和方法

因?yàn)樵贓CMAScript中函數(shù)是對(duì)象,因此函數(shù)也有屬性和方法。

每個(gè)函數(shù)包含兩個(gè)屬性:lengthprototype

length表示函數(shù)接受的參數(shù)的個(gè)數(shù)

function sayName(name) {
  console.log(name);
}

function sum(sum1, sum2) {
  return num1 + num2;
}

function sayHi() {
  console.log("Hi!");
}

console.log(sayName.length);  //1
console.log(sum.length);      //2
console.log(sayHi.length);    //0

另一個(gè)屬性prototype是保存引用類型所有實(shí)例方法的真正所在,比如toString()valueOf()等方法都保存在prototype名下,prototype在實(shí)現(xiàn)繼承時(shí)非常重要,下一篇我們?cè)僦v。

每個(gè)函數(shù)都包含兩個(gè)非繼承來(lái)的方法:apply()call()

apply()call()都是在特定的作用域中調(diào)用函數(shù),等于設(shè)置函數(shù)體內(nèi)this的值,他們的區(qū)別在于:
apply()接受兩個(gè)參數(shù):一個(gè)是在其中運(yùn)行函數(shù)的作用域,另一個(gè)是參數(shù)數(shù)組,既可以是Array實(shí)例,也可以是arguements對(duì)象。
call()第一個(gè)參數(shù)和apply()一樣,但是傳遞參數(shù)的時(shí)候,必須逐個(gè)例舉出來(lái)。

function sum(num1, num2) {
  return num1 + num2;
}

function callSum1(num1, num2) {
  return sum.apply(this, arguments);   //傳入arguments字符串
}

function callSum2(num1, num2) {
  return sum.apply(this, [num1,num2]);  //傳入數(shù)組
}

function callSum3(num1, num2) {
  return sum.call(this, num1, num2);   //使用call必須把參數(shù)列舉出來(lái)
}

console.log(callSum1(10,10));   //20
console.log(callSum2(10,10));   //20
console.log(callSum3(10,10));   //20

既然apply()call()的參數(shù)有作用域,那么是用來(lái)干什么的呢?看下面的例子:

window.color = "red";
var 0 = { color: "blue" };

function sayColor() {
  console.log(this.color);
}

sayColor();                //red
sayColor.call(this)        //red
sayColor.call(window)      //red
sayColor.call(o)           //blue

是不是this的值又懵了?如果懵了,就翻上去看方方老師那篇文章。
沒(méi)錯(cuò),apply()call()的作用就是擴(kuò)充函數(shù)的作用域

大概就是這么多了,書上這一章的內(nèi)容我反復(fù)看了好幾遍才理解,所以學(xué)習(xí)哪有什么捷徑,無(wú)他,唯手熟爾
那么,聰明的你,看完之后懂了沒(méi)有?
下一篇準(zhǔn)備講原型

最后編輯于
?著作權(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)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

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

  • 本文檔內(nèi)容參考 《JavaScript 闖關(guān)記》之函數(shù) 函數(shù)是一段代碼,它只定義一次,但可以被執(zhí)行或調(diào)用任意次。在...
    穿越人海遇見你閱讀 1,105評(píng)論 0 1
  • Chapter 5 引用類型 Object類型 創(chuàng)建Object實(shí)例new Object()var person ...
    云之外閱讀 437評(píng)論 0 0
  • 第5章 引用類型(返回首頁(yè)) 本章內(nèi)容 使用對(duì)象 創(chuàng)建并操作數(shù)組 理解基本的JavaScript類型 使用基本類型...
    大學(xué)一百閱讀 3,667評(píng)論 0 4
  • Function類型 函數(shù)實(shí)際上是對(duì)象,每個(gè)函數(shù)都是Function類型的實(shí)例,而且都與其他引用類型一樣具有屬性和...
    胖胖冰閱讀 1,050評(píng)論 0 8
  • 第一章: JS簡(jiǎn)介 從當(dāng)初簡(jiǎn)單的語(yǔ)言,變成了現(xiàn)在能夠處理復(fù)雜計(jì)算和交互,擁有閉包、匿名函數(shù), 甚至元編程等...
    LaBaby_閱讀 1,751評(píng)論 0 6

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