帶你學習Javascript中的函數進階(一)

1. 函數的定義和調用

1.1 函數的定義方式

  1. 函數聲明方式function關鍵字(命名函數)
  2. 函數表達式(匿名函數)
  3. new Function()
var fn = new Function('參數1', '參數2',...,'函數體')
  • Function裏面參數都必須是字符串格式
  • 第三種方式執行效率低,也不方便書寫,用的比較少
  • 所有函數都是Function的實例(對象)
//函數聲明方式
function fn() {}

//函數表達式(匿名函數)
var fn = function() {}

//利用new Function('arg1','arg2', 'fn')
var f = new Function('a','b',console.log(a+b)')
f(1,2) // 3

所有的函數都是Function實例對象
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-BJzzyoaF-1583129073592)(https://cdn.nlark.com/yuque/0/2020/png/148146/1583069785134-c58604dc-ecf6-4d54-8cb6-bd43338329db.png#align=left&display=inline&height=303&name=image.png&originHeight=606&originWidth=1678&size=255639&status=done&style=none&width=839)]

1.2 函數的調用方式

  1. 普通函數
  2. 對象的方法
  3. 構造函數
  4. 綁定事件函數
  5. 定時器函數
  6. 立即執行函數
// 普通函數
function fn() {
	console.log('前端嵐楓博客')
}
fn() //前端嵐楓博客

//對象的方法
var obj = {
	say: function () {
  	console.log('前端嵐楓博客')
  }
}
obj.say() //前端嵐楓博客

//構造函數
function Star() {
}
new Star()

//綁定的事件函數
btn.onclick = function() {} //點擊了按鈕就可以調用該函數

//定時器函數
setInterval(function() {}, 1000)

//立即執行函數
(function() {
	console.log('前端嵐楓博客') //自動調用
})()

2. this

2.1 函數內this的指向

這些this的指向,是當調用函數的時候確定的調用方法的不同決定了this的指向不同,一般指向調用者。
調用方式

調用方式 this指向
普通函數調用 window
構造函數調用 實例對象 原型對象裏面的方法也指向實例對象
對象方法調用 該方法所屬對象
事件綁定方法 綁定事件對象
定時器函數
window
立即執行函數 window

2.2 改變函數內部this指向

Javascript爲提供了一些函數方法來幫助我們更優雅地處理函數內部this的指向問題,常用的有bind()、call()、apply()三種方法。接下來,我們來詳細的介紹一下這三種方法的用法,看看它們是如何改變this指向的。

  1. call方法

call()方法調用一個對象,簡單理解爲調用函數的方式,但是它可以改變函數的this指向。

fn.call(thisArg, arg1, arg2, ...)
var obj = {
		name: 'lanfeng'
}
function fn(a, b) {
	console.log(this) 
  console.log(a+b) 
}
fn(1,2)//指向window, 3
fn.call(obj, 1, 2) //指向obj, 3

//實現繼承
function Father(uname, age, sex) {
	this.uname = uname
  this.age = age
  this.sex = sex
}
function Son () {
	Father.call(this,uname, age, sex)
}
var son = new Son('柳巖',18,'女')

call:第一個可以調用函數,第二個可以改變函數內的this指向
call的主要作用可以實現繼承

  1. apply方法

apply()方法調用一個函數。簡單理解爲調用函數的方式,它與call方法一樣可以改變函數的this的指向,但是它跟call傳參數方式不一樣,它是傳的參數必須在一個數組裏

fun.apply(thisArg, [argsArray])
  • thisArg:在fun函數運行時指定this的值
  • argsArray: 傳遞的值,必須包含在數組裏面
  • 返回值就是函數的返回值,因爲它就是調用函數
var obj = {
		name: 'lanfeng'
}
function fn(a, b) {
	console.log(this) 
  console.log(a+b) 
}
fn(1,2)//指向window, 3
fn.apply(obj, [1, 2]) //指向obj, 3

apply:第一個可以調用函數,第二個可以改變函數內的this指向
apply的參數必須時數組(僞數組)
apply的主要應用,求數數組中的最大值,最小值

var arr = [1, 66, 3, 99, 4]
var max = Math.max.apply(Math, arr) 
var min = Math.min.apply(Math, arr) 
console.log(max, min) //99 1
  1. bind方法

bind()方法不會調用函數,但是能改變函數內部this指向

fn.bind(thisArg, arg1, arg2, ...)
  • thisArg: 在fn函數運行時指定的this值
  • arg1, arg2: 傳遞的其他參數
  • 返回由指定的this值和初始化參數改造的原函數拷貝
var obj = {
		name: 'lanfeng'
}
function fn(a, b) {
	console.log(this) 
  console.log(a+b) 
}
fn(1,2)//指向window, 3
var f = fn.bind(obj, 1, 2)
f()

bind: 不會調原來的函數,可以改變this指向,返回的函數是改變this之後產生的新函數
bind的應用: 如果有的函數我們不需要立即調用,但是又想改變這個函數內部的this指向此時用bind

var btn = document.querySelector('button')
//以前的用法
btn.onclick = function() {
  var that = this
	this.disabled = true
  setTimeout(function(){
  	that.disabled = false
  }, 3000)
}

// bind用法
btn.onclick = function() {
	this.disabled = true
  setTimeout(function(){
  	this.disabled = false
  }.bind(this), 3000)
}

2.3 call apply bind 總結

相同點:
都可以改變函數內部的this指向
區別點:

  1. call 和apply 會調用函數,並且改變函數內部的this指向
  2. call和apply傳遞的參數不一樣,call傳遞參數形式arg1, arg2, …形式,apply必須數組形式
  3. bind不會調用函數,可以改變函數內部的this指向

主要應用場景:

  1. call經常做繼承
  2. apply經常跟數組有關係,比如藉助於數學對象實現數組的最大值最小值
  3. bind不調用函數,但是還想改變this指向,比如改變定時器的內部this指向

總結

本篇文章主要分享了javascript的函數定義、用法、this及改變this指向的幾種方法

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章