javascript
JavaScript中的函数
文章目錄
- 函數
- 函數的定義方式
- 函數聲明
- 函數表達式
- 函數聲明與函數表達式的區別
- 函數的調用方式
- 函數內 `this` 指向的不同場景
- 函數也是對象
- 數組的函數調用
- call、apply、bind方法
- call
- apply
- bind
- 小結
- 函數的其它成員
- 高階函數
- 作為參數
- 作為返回值
函數
函數的定義方式
- 函數聲明
- 函數表達式
- new Function
函數聲明
function foo () {}函數表達式
var foo = function () {}函數聲明與函數表達式的區別
- 函數聲明必須有名字
- 函數聲明會函數提升,在預解析階段就已創建,聲明前后都可以調用
- 函數表達式類似于變量賦值
- 函數表達式可以沒有名字,例如匿名函數
- 函數表達式沒有變量提升,在執行階段創建,必須在表達式執行之后才可以調用
下面是一個根據條件定義函數的例子:
if (true) {function f () {console.log(1)} } else {function f () {console.log(2)} }以上代碼執行結果在不同瀏覽器中結果不一致。
不過我們可以使用函數表達式解決上面的問題:
var fif (true) {f = function () {console.log(1)} } else {f = function () {console.log(2)} }函數的調用方式
- 普通函數
- 構造函數
- 對象方法
函數內 this 指向的不同場景
函數的調用方式決定了 this 指向的不同:
普通函數中的this是誰?-----window對象.方法中的this是誰?----當前的實例對象定時器方法中的this是誰?----window構造函數中的this是誰?-----實例對象原型對象方法中的this是誰?---實例對象| 普通函數調用 | window | 嚴格模式下是 undefined |
| 構造函數調用 | 實例對象 | 原型方法中 this 也是實例對象 |
| 對象方法調用 | 該方法所屬對象 | 緊挨著的對象 |
| 事件綁定方法 | 綁定事件對象 | |
| 定時器函數 | window |
函數也是對象
- 所有函數都是 Function 的實例
- 對象中有__proto__原型,是對象
- 函數中有prototype原型,是對象
數組的函數調用
<script>//數組可以存儲任何類型的數據var arr=[function () {console.log("十一假期快樂");},function () {console.log("十一假期開心");},function () {console.log("十一假期健康");},function () {console.log("十一假期安全");},function () {console.log("十一假期如意");}];//回調函數:函數作為參數使用arr.forEach(function (ele) {ele();});</script>call、apply、bind方法
那了解了函數 this 指向的不同場景之后,我們知道有些情況下我們為了使用某種特定環境的 this 引用,
這時候時候我們就需要采用一些特殊手段來處理了,例如我們經常在定時器外部備份 this 引用,然后在定時器函數內部使用外部 this 的引用。
然而實際上對于這種做法我們的 JavaScript 為我們專門提供了一些函數方法用來幫我們更優雅的處理函數內部 this 指向問題。即 call、apply、bind 三個函數方法。
call
call() 方法調用一個函數, 其具有一個指定的 this 值和分別地提供的參數(參數的列表)。
注意:該方法的作用和 `apply()` 方法類似,只有一個區別,就是 `call()` 方法接受的是若干個參數的列表,而 `apply()` 方法接受的是一個包含多個參數的數組。
語法:
fun.call(thisArg, arg1[, arg2[, ...]]])參數:
- thisArg
- 在 fun 函數運行時指定的 this 值
- 如果指定了 null 或者 undefined 則內部 this 指向 window
- arg1, arg2, ...
- 指定的參數列表
apply
apply() 方法調用一個函數, 其具有一個指定的 this 值,以及作為一個數組(或類似數組的對象)提供的參數。
注意:該方法的作用和 `call()` 方法類似,只有一個區別,就是 `call()` 方法接受的是若干個參數的列表,而 `apply()` 方法接受的是一個包含多個參數的數組。
語法:
fun.apply(thisArg, [argsArray])參數:
- thisArg
- argsArray
apply() 與 call() 非常相似,不同之處在于提供參數的方式。
apply() 使用參數數組而不是一組參數列表。例如:
bind
bind() 函數會創建一個新函數(稱為綁定函數),新函數與被調函數(綁定函數的目標函數)具有相同的函數體(在 ECMAScript 5 規范中內置的call屬性)。
當目標函數被調用時 this 值綁定到 bind() 的第一個參數,該參數不能被重寫。綁定函數被調用時,bind() 也接受預設的參數提供給原函數。
一個綁定函數也能使用new操作符創建對象:這種行為就像把原函數當成構造器。提供的 this 值被忽略,同時調用時的參數被提供給模擬函數。
語法:
fun.bind(thisArg[, arg1[, arg2[, ...]]])參數:
- thisArg
- 當綁定函數被調用時,該參數會作為原函數運行時的 this 指向。當使用new 操作符調用綁定函數時,該參數無效。
- arg1, arg2, …
- 當綁定函數被調用時,這些參數將置于實參之前傳遞給被綁定的方法。
返回值:
返回由指定的this值和初始化參數改造的原函數拷貝。
function f1(x, y) {console.log((x + y) + ":=====>" + this.age);}var ff=f1.bind(null);ff(10,20);復制了一份的時候,把參數傳入到了f1函數中,x===>10,y===>20,null就是this,默認就是windowbind方法是復制的意思,參數可以在復制的時候傳進去,也可以在復制之后調用的時候傳入進去apply和call是調用的時候改變this指向bind方法,是賦值一份的時候,改變了this的指向,bind方法不調用調用方法不停產生隨機數實例:
<script>//通過對象,調用方法,產生隨機數function ShowRandom() {//1-10的隨機數this.number=parseInt(Math.random()*10+1);}//添加原型方法ShowRandom.prototype.show1=function () {//改變了定時器中的this的指向了,本來應該是window,現在是實例對象了window.setInterval(this.show2.bind(this),1000);};//添加原型方法ShowRandom.prototype.show2=function () {//顯示隨機數--console.log(this.number);};//實例對象var sr=new ShowRandom();//調用方法,輸出隨機數字//調用這個方法一次,可以不停的產生隨機數字sr.show1();</script>小結
- call 和 apply 區別:
call 和 apply共同點
只要是想使用別的對象的方法,并且希望這個方法是當前對象的,那么就可以使用apply或者是call的方法改變this的指向都是用來調用函數,而且是立即調用但是可以在調用函數的同時,通過第一個參數指定函數內部 `this` 的指向如果第一個參數指定了 `null` 或者 `undefined` 則內部 this 指向 windowapply和call方法實際上并不在函數這個實例對象中,而是在Function的prototype中- bind
函數的其它成員
- arguments
- 實參集合
- caller
- 函數的調用者
- length
- 形參的個數
- name
- 函數的名稱
高階函數
- 函數可以作為參數
- 函數可以作為返回值
作為參數
function eat (callback) {setTimeout(function () {console.log('吃完了')callback()}, 1000) }eat(function () {console.log('去唱歌') })作為返回值
function genFun (type) {return function (obj) {return Object.prototype.toString.call(obj) === type} }var isArray = genFun('[object Array]') var isObject = genFun('[object Object]')console.log(isArray([])) // => true console.log(isArray({})) // => true總結
以上是生活随笔為你收集整理的JavaScript中的函数的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: android来电自定义显示图片,安卓手
- 下一篇: 做工作必须将心比心——感谢译者陈浩对我们