詳解JavaScript的三種this指向方法
講一下call()方法
在 JavaScript 中,call()
方法用于調(diào)用一個函數(shù),可以指定函數(shù)體內(nèi) this
對象的值。這里的 this
指的是函數(shù)執(zhí)行時所在的上下文對象,也就是函數(shù)執(zhí)行時所處的環(huán)境,同時可以傳遞參數(shù)列表來執(zhí)行函數(shù)。
call()
方法接受的第一個參數(shù)是要綁定給 this
的值,后面的參數(shù)是傳遞給函數(shù)的參數(shù)列表。通過 call()
方法,可以改變函數(shù)內(nèi)部 this
的指向,并且立即執(zhí)行函數(shù)。
以下是 call()
方法的語法:
functionName.call(thisArg, arg1, arg2, ...)
functionName
:要調(diào)用的函數(shù)名稱。thisArg
:函數(shù)執(zhí)行時綁定的this
值,即函數(shù)內(nèi)部的上下文對象。arg1, arg2, ...
:要傳遞給函數(shù)的參數(shù)列表。
當調(diào)用 call()
方法時,它會立即執(zhí)行函數(shù),并將指定的 thisArg
綁定到函數(shù)內(nèi)部的 this
上下文。這意味著函數(shù)內(nèi)部的 this
將引用 thisArg
所指定的對象。
另外,call()
方法還可以接受多個參數(shù)作為函數(shù)的參數(shù)列表,并依次傳遞給函數(shù)。
下面是一個使用 call()
方法的簡單例子:
const person = { fullName: function() { return this.firstName + " " + this.lastName; } } const person1 = { firstName: "John", lastName: "Doe" } const person2 = { firstName: "Mary", lastName: "Doe" } // 使用 call() 方法指定 person1 作為函數(shù)內(nèi)部的 this 對象 const fullName1 = person.fullName.call(person1); // 返回 "John Doe" // 使用 call() 方法指定 person2 作為函數(shù)內(nèi)部的 this 對象 const fullName2 = person.fullName.call(person2); // 返回 "Mary Doe"
在上面的例子中,call()
方法被用于在不同的上下文中調(diào)用 person.fullName()
函數(shù)。通過使用 call()
方法,我們可以指定函數(shù)內(nèi)部 this
的值,并且讓函數(shù)在不同的上下文中執(zhí)行,從而達到我們的目的。
使用 call()
方法的主要場景包括:
- 顯式設(shè)置函數(shù)內(nèi)部的
this
上下文。 - 在借用其他對象的方法時,將當前對象作為
this
上下文。 - 調(diào)用函數(shù)并傳遞參數(shù)列表。
總結(jié):
call()
方法用于調(diào)用一個函數(shù)并設(shè)置函數(shù)內(nèi)部的this
值。它接受一個對象作為thisArg
,將該對象綁定到函數(shù)內(nèi)部的this
上下文,并可以傳遞參數(shù)列表給函數(shù)。這個方法常用于顯式設(shè)置函數(shù)的執(zhí)行上下文和借用其他對象的方法。
講一下bind()方法
bind()
方法是 JavaScript 中的一個內(nèi)置函數(shù),用于創(chuàng)建一個新的函數(shù),這個新函數(shù)與原函數(shù)綁定了指定的 this
對象和部分參數(shù),并且在調(diào)用時這些參數(shù)會被預先傳入。bind()
方法的語法如下:
functionName.bind(thisArg, arg1, arg2, ...)
functionName
:要綁定上下文的函數(shù)名稱。thisArg
(必選參數(shù)):函數(shù)執(zhí)行時綁定的this
值,即函數(shù)內(nèi)部的上下文對象。arg1, arg2, ...
(可選參數(shù)):要預設(shè)的參數(shù)列表。
bind()
方法會返回一個新的函數(shù),該新函數(shù)的 this
值被永久地綁定到 thisArg
所指定的對象。當調(diào)用這個新函數(shù)時,它會以指定的上下文執(zhí)行,并將預設(shè)的 arg1
、arg2
等參數(shù)預先傳入新函數(shù)。
使用 bind()
方法,可以實現(xiàn)改變函數(shù)內(nèi)部的 this
指向,以及部分參數(shù)的預先傳入。這個方法在一些特定的場景下非常有用,比如在回調(diào)函數(shù)中使用,可以解決 this
指向問題。例如:
示例一:
var person = { name: "John", greet: function (message) { console.log(message + ", " + this.name); }, }; var anotherPerson = { name: "Ben", }; var boundGreet = person.greet.bind(person, "Hello"); boundGreet(); // 輸出:Hello, John var boundGreet = person.greet.bind(anotherPerson, "Hello"); boundGreet(); // 輸出:Hello, Ben
示例二:
const obj = { name: 'Tom', sayHi() { console.log(`Hi, my name is ${this.name}`); }, }; // 在回調(diào)函數(shù)中使用 bind() 方法改變 sayHi() 函數(shù)內(nèi)部的 this 指向 setTimeout(obj.sayHi(), 1000); // 立即執(zhí)行 輸出:Hi, my name is Tom setTimeout(obj.sayHi.bind(obj), 1000); // 1s后執(zhí)行 輸出:Hi, my name is Tom
上面代碼直接用 setTimeout(obj.sayHi(), 1000); 不也可以,為什么還要加上bind()
上面代碼直接使用
setTimeout(obj.sayHi(), 1000)
會立即調(diào)用obj.sayHi()
函數(shù),并把它的返回值作為第一個參數(shù)傳遞給setTimeout()
函數(shù),相當于setTimeout(undefined, 1000)
。所以實際上是沒有等待1秒后再執(zhí)行sayHi()
的效果的。而
setTimeout(obj.sayHi.bind(obj), 1000)
中,bind()
方法會返回一個綁定了obj
作為上下文的新函數(shù),并不會立即調(diào)用。所以setTimeout()
函數(shù)會等待1秒后再調(diào)用這個新函數(shù),保證了1秒后再執(zhí)行sayHi()
函數(shù)。
又例如,預先傳入部分參數(shù)的情況:
function add(x, y) { return x + y; } // 使用 bind() 方法預先傳入?yún)?shù) 1,得到一個新的函數(shù) const addOne = add.bind(null, 1); console.log(addOne(2)); // 輸出:3
在上面的例子中,使用 bind()
方法預先傳入了參數(shù) 1
,得到一個新的函數(shù) addOne
,在調(diào)用這個新函數(shù)時,只需要再傳入一個參數(shù) 2
,即可完成 1 + 2
的操作。
講一下apply方法
apply()
方法是 JavaScript 中的一個函數(shù)方法,用于在特定的作用域中調(diào)用函數(shù),并將參數(shù)以數(shù)組形式傳遞。
語法:
function.apply(thisArg, [argsArray])
參數(shù)說明:
thisArg
:可選參數(shù),指定函數(shù)執(zhí)行時的作用域?qū)ο?。在函?shù)內(nèi)部使用this
關(guān)鍵字時,將引用該參數(shù)指定的對象。如果省略或傳入null
或undefined
,則在調(diào)用時使用全局對象(通常是window
對象)作為作用域。argsArray
:可選參數(shù),一個數(shù)組或類數(shù)組對象,包含傳遞給函數(shù)的參數(shù)。如果省略或傳入null
或undefined
,則表示不傳遞任何參數(shù)。
使用 apply()
方法可以實現(xiàn)以下功能:
- 在特定作用域中調(diào)用函數(shù):通過指定
thisArg
參數(shù),可以在特定對象的作用域中執(zhí)行函數(shù),修改函數(shù)內(nèi)部的this
引用。 - 傳遞參數(shù)數(shù)組:將參數(shù)以數(shù)組形式傳遞給函數(shù),可以方便地在調(diào)用函數(shù)時動態(tài)傳遞參數(shù)。
示例:
function greet(name, age) { console.log(`Hello, ${name}! You are ${age} years old.`); } const person = { name: 'Alice', age: 25 }; greet.apply(person, ['Bob', 30]); // 輸出:Hello, Bob! You are 30 years old. // 相當于在person對象作用域里面打印了 "Hello, Bob! You are 30 years old." 打招呼的話
在上面的示例中,我們定義了一個 greet
函數(shù)用于打招呼,接受一個 name
參數(shù)和一個 age
參數(shù)。然后,我們創(chuàng)建了一個 person
對象,包含 name
和 age
屬性。通過使用 apply()
方法,我們將 person
對象作為函數(shù)調(diào)用的作用域,并傳遞一個包含 'Bob'
和 30
的參數(shù)數(shù)組。最終,函數(shù)在 person
對象的作用域中執(zhí)行,并輸出相應的結(jié)果。
apply和call的區(qū)別
需要注意的是,apply()
方法和 call()
方法的作用類似,唯一的區(qū)別是參數(shù)的傳遞方式不同。apply()
方法使用數(shù)組形式傳遞參數(shù),而 call()
方法使用逐個參數(shù)傳遞。
apply()其他應用場景
當使用 apply()
方法時,還可以在某些情況下提供更靈活和動態(tài)的函數(shù)調(diào)用。以下是一些使用 apply()
方法的其他例子:
動態(tài)改變函數(shù)的上下文:
function greet() { console.log(`Hello, ${this.name}!`); } const person1 = { name: 'Alice' }; const person2 = { name: 'Bob' }; greet.apply(person1); // 輸出:Hello, Alice! greet.apply(person2); // 輸出:Hello, Bob!
通過使用 apply()
方法,可以動態(tài)地將不同的對象作為函數(shù)調(diào)用的上下文(this
)。
數(shù)組操作:
const numbers = [1, 2, 3, 4, 5]; const max = Math.max.apply(null, numbers); const min = Math.min.apply(null, numbers); // const max = Math.max(...numbers); // const min = Math.min(...numbers); console.log(max); // 輸出:5 console.log(min); // 輸出:1
在這個例子中,通過使用 apply()
方法,將數(shù)組作為參數(shù)傳給 Math.max()
和 Math.min()
函數(shù),從而得到數(shù)組中的最大值和最小值。
配合
arguments
對象使用:
function sum() { // 將 arguments 對象轉(zhuǎn)換為真正的數(shù)組 const argsArray = Array.prototype.slice.call(arguments); // 使用 reduce 方法對數(shù)組中的元素進行累加求和,初始值為 0 return argsArray.reduce((total, num) => total + num, 0); // 這里傳入的實參0是可選參數(shù)initialValue,用于指定累積的初始值 // 如果沒有提供初始值,則將使用數(shù)組的第一個元素作為初始值,并從第二個元素開始進行迭代。 // 所以不寫也是OK的,結(jié)果相同 } const numbers = [1, 2, 3, 4, 5]; // 使用 apply 方法將 numbers 數(shù)組作為參數(shù)傳遞給 sum 函數(shù),并執(zhí)行求和操作 const result = sum.apply(null, numbers); console.log(result); // 輸出:15
在這個例子中,sum()
函數(shù)接收任意數(shù)量的參數(shù),并使用 apply()
方法將參數(shù)數(shù)組傳遞給函數(shù)。通過將 arguments
對象轉(zhuǎn)換為真正的數(shù)組,我們可以對參數(shù)進行操作,例如在此例中計算它們的總和。
總之,apply()
方法提供了一種動態(tài)調(diào)用函數(shù)的方式,并且在某些情況下非常有用,特別是在需要改變函數(shù)上下文、操作數(shù)組或處理不定數(shù)量的參數(shù)時。
以上就是詳解JavaScript的三種this指向方法的詳細內(nèi)容,更多關(guān)于JavaScript this指向的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
js利用FileReader實現(xiàn)圖片轉(zhuǎn)base64格式并上傳預覽頭像
本文主要介紹了js利用FileReader實現(xiàn)圖片轉(zhuǎn)base64格式并上傳預覽頭像,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2022-05-05JavaScript實現(xiàn)節(jié)點的刪除與序號重建實例
這篇文章主要介紹了JavaScript實現(xiàn)節(jié)點的刪除與序號重建方法,涉及javascript針對頁面節(jié)點的刪除與遍歷技巧,非常具有實用價值,需要的朋友可以參考下2015-08-08JavaScript實現(xiàn)動態(tài)增刪表格的方法
本篇文章主要介紹了JavaScript實現(xiàn)動態(tài)增刪表格,可以實現(xiàn)表格增加和刪除數(shù)據(jù)的功能,非常具有實用價值,有興趣的可以了解一下2017-03-03npm install報錯無法創(chuàng)建packge.json文件的解決辦法
當你在運行 npm install 時遇到錯誤,提示無法找到 package.json 文件,也沒有創(chuàng)建一個 package.json 文件,只創(chuàng)建了一個package-lock.json文件,本文給大家介紹詳細的解決辦法,需要的朋友可以參考下2024-02-02