詳解JavaScript的三種this指向方法
講一下call()方法
在 JavaScript 中,call() 方法用于調(diào)用一個(gè)函數(shù),可以指定函數(shù)體內(nèi) this 對象的值。這里的 this 指的是函數(shù)執(zhí)行時(shí)所在的上下文對象,也就是函數(shù)執(zhí)行時(shí)所處的環(huán)境,同時(shí)可以傳遞參數(shù)列表來執(zhí)行函數(shù)。
call() 方法接受的第一個(gè)參數(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í)行時(shí)綁定的this值,即函數(shù)內(nèi)部的上下文對象。arg1, arg2, ...:要傳遞給函數(shù)的參數(shù)列表。
當(dāng)調(diào)用 call() 方法時(shí),它會立即執(zhí)行函數(shù),并將指定的 thisArg 綁定到函數(shù)內(nèi)部的 this 上下文。這意味著函數(shù)內(nèi)部的 this 將引用 thisArg 所指定的對象。
另外,call() 方法還可以接受多個(gè)參數(shù)作為函數(shù)的參數(shù)列表,并依次傳遞給函數(shù)。
下面是一個(gè)使用 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í)行,從而達(dá)到我們的目的。
使用 call() 方法的主要場景包括:
- 顯式設(shè)置函數(shù)內(nèi)部的
this上下文。 - 在借用其他對象的方法時(shí),將當(dāng)前對象作為
this上下文。 - 調(diào)用函數(shù)并傳遞參數(shù)列表。
總結(jié):
call()方法用于調(diào)用一個(gè)函數(shù)并設(shè)置函數(shù)內(nèi)部的this值。它接受一個(gè)對象作為thisArg,將該對象綁定到函數(shù)內(nèi)部的this上下文,并可以傳遞參數(shù)列表給函數(shù)。這個(gè)方法常用于顯式設(shè)置函數(shù)的執(zhí)行上下文和借用其他對象的方法。
講一下bind()方法
bind() 方法是 JavaScript 中的一個(gè)內(nèi)置函數(shù),用于創(chuàng)建一個(gè)新的函數(shù),這個(gè)新函數(shù)與原函數(shù)綁定了指定的 this 對象和部分參數(shù),并且在調(diào)用時(shí)這些參數(shù)會被預(yù)先傳入。bind() 方法的語法如下:
functionName.bind(thisArg, arg1, arg2, ...)
functionName:要綁定上下文的函數(shù)名稱。thisArg(必選參數(shù)):函數(shù)執(zhí)行時(shí)綁定的this值,即函數(shù)內(nèi)部的上下文對象。arg1, arg2, ...(可選參數(shù)):要預(yù)設(shè)的參數(shù)列表。
bind() 方法會返回一個(gè)新的函數(shù),該新函數(shù)的 this 值被永久地綁定到 thisArg 所指定的對象。當(dāng)調(diào)用這個(gè)新函數(shù)時(shí),它會以指定的上下文執(zhí)行,并將預(yù)設(shè)的 arg1、arg2 等參數(shù)預(yù)先傳入新函數(shù)。
使用 bind() 方法,可以實(shí)現(xiàn)改變函數(shù)內(nèi)部的 this 指向,以及部分參數(shù)的預(yù)先傳入。這個(gè)方法在一些特定的場景下非常有用,比如在回調(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ù),并把它的返回值作為第一個(gè)參數(shù)傳遞給setTimeout()函數(shù),相當(dāng)于setTimeout(undefined, 1000)。所以實(shí)際上是沒有等待1秒后再執(zhí)行sayHi()的效果的。而
setTimeout(obj.sayHi.bind(obj), 1000)中,bind()方法會返回一個(gè)綁定了obj作為上下文的新函數(shù),并不會立即調(diào)用。所以setTimeout()函數(shù)會等待1秒后再調(diào)用這個(gè)新函數(shù),保證了1秒后再執(zhí)行sayHi()函數(shù)。
又例如,預(yù)先傳入部分參數(shù)的情況:
function add(x, y) {
return x + y;
}
// 使用 bind() 方法預(yù)先傳入?yún)?shù) 1,得到一個(gè)新的函數(shù)
const addOne = add.bind(null, 1);
console.log(addOne(2)); // 輸出:3
在上面的例子中,使用 bind() 方法預(yù)先傳入了參數(shù) 1,得到一個(gè)新的函數(shù) addOne,在調(diào)用這個(gè)新函數(shù)時(shí),只需要再傳入一個(gè)參數(shù) 2,即可完成 1 + 2 的操作。
講一下apply方法
apply() 方法是 JavaScript 中的一個(gè)函數(shù)方法,用于在特定的作用域中調(diào)用函數(shù),并將參數(shù)以數(shù)組形式傳遞。
語法:
function.apply(thisArg, [argsArray])
參數(shù)說明:
thisArg:可選參數(shù),指定函數(shù)執(zhí)行時(shí)的作用域?qū)ο?。在函?shù)內(nèi)部使用this關(guān)鍵字時(shí),將引用該參數(shù)指定的對象。如果省略或傳入null或undefined,則在調(diào)用時(shí)使用全局對象(通常是window對象)作為作用域。argsArray:可選參數(shù),一個(gè)數(shù)組或類數(shù)組對象,包含傳遞給函數(shù)的參數(shù)。如果省略或傳入null或undefined,則表示不傳遞任何參數(shù)。
使用 apply() 方法可以實(shí)現(xiàn)以下功能:
- 在特定作用域中調(diào)用函數(shù):通過指定
thisArg參數(shù),可以在特定對象的作用域中執(zhí)行函數(shù),修改函數(shù)內(nèi)部的this引用。 - 傳遞參數(shù)數(shù)組:將參數(shù)以數(shù)組形式傳遞給函數(shù),可以方便地在調(diào)用函數(shù)時(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.
// 相當(dāng)于在person對象作用域里面打印了 "Hello, Bob! You are 30 years old." 打招呼的話
在上面的示例中,我們定義了一個(gè) greet 函數(shù)用于打招呼,接受一個(gè) name 參數(shù)和一個(gè) age 參數(shù)。然后,我們創(chuàng)建了一個(gè) person 對象,包含 name 和 age 屬性。通過使用 apply() 方法,我們將 person 對象作為函數(shù)調(diào)用的作用域,并傳遞一個(gè)包含 'Bob' 和 30 的參數(shù)數(shù)組。最終,函數(shù)在 person 對象的作用域中執(zhí)行,并輸出相應(yīng)的結(jié)果。
apply和call的區(qū)別
需要注意的是,apply() 方法和 call() 方法的作用類似,唯一的區(qū)別是參數(shù)的傳遞方式不同。apply() 方法使用數(shù)組形式傳遞參數(shù),而 call() 方法使用逐個(gè)參數(shù)傳遞。
apply()其他應(yīng)用場景
當(dāng)使用 apply() 方法時(shí),還可以在某些情況下提供更靈活和動態(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
在這個(gè)例子中,通過使用 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ù)組中的元素進(jìn)行累加求和,初始值為 0
return argsArray.reduce((total, num) => total + num, 0);
// 這里傳入的實(shí)參0是可選參數(shù)initialValue,用于指定累積的初始值
// 如果沒有提供初始值,則將使用數(shù)組的第一個(gè)元素作為初始值,并從第二個(gè)元素開始進(jìn)行迭代。
// 所以不寫也是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
在這個(gè)例子中,sum() 函數(shù)接收任意數(shù)量的參數(shù),并使用 apply() 方法將參數(shù)數(shù)組傳遞給函數(shù)。通過將 arguments 對象轉(zhuǎn)換為真正的數(shù)組,我們可以對參數(shù)進(jìn)行操作,例如在此例中計(jì)算它們的總和。
總之,apply() 方法提供了一種動態(tài)調(diào)用函數(shù)的方式,并且在某些情況下非常有用,特別是在需要改變函數(shù)上下文、操作數(shù)組或處理不定數(shù)量的參數(shù)時(shí)。
以上就是詳解JavaScript的三種this指向方法的詳細(xì)內(nèi)容,更多關(guān)于JavaScript this指向的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
JavaScript實(shí)現(xiàn)一個(gè)簡易的計(jì)算器實(shí)例代碼
這篇文章主要介紹了JavaScript實(shí)現(xiàn)一個(gè)簡易的計(jì)算器實(shí)例代碼,具有很好的參考價(jià)值,希望對大家有所幫助,一起跟隨小編過來看看吧2018-05-05
JavaScript實(shí)現(xiàn)的簡單煙花特效代碼
這篇文章主要介紹了JavaScript實(shí)現(xiàn)的簡單煙花特效代碼,涉及JavaScript數(shù)學(xué)運(yùn)算及頁面元素基于定時(shí)函數(shù)運(yùn)動的相關(guān)技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-10-10
JavaScript使用JSEncrypt對數(shù)據(jù)加解密
文章介紹了在Web開發(fā)中使用RSA非對稱加密算法保護(hù)敏感信息的方法,詳細(xì)講解了JSEncrypt庫的安裝、使用和注意事項(xiàng),此外,還提供了生成公私鑰、動態(tài)獲取公鑰以及安全性建議等實(shí)用內(nèi)容,需要的朋友可以參考下2026-05-05
js實(shí)現(xiàn)格式化金額,字符,時(shí)間的方法
這篇文章主要介紹了js實(shí)現(xiàn)格式化金額,字符,時(shí)間的方法,實(shí)例分析了javascript轉(zhuǎn)換金額、字符、日期等的常用技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-02-02
JavaScript實(shí)現(xiàn)輕松創(chuàng)建二維數(shù)組的方法小結(jié)
這篇文章主要為大家詳細(xì)介紹了JavaScript中實(shí)現(xiàn)輕松創(chuàng)建二維數(shù)組的多種方法,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2024-04-04
javascript add event remove event
javascript事件綁定和刪除功能代碼2008-04-04
JavaScript Window瀏覽器對象模型方法與屬性匯總
本文給大家匯總分享的是JavaScript Window瀏覽器對象模型方法與屬性,十分的細(xì)致全面,這里推薦給大家,有需要的小伙伴可以參考下。2015-04-04

