關於JS中apply和call詳細解答
今天學習的是apply和call,他們是我們作為前端入門必須掌握的知識點,廢話不多說開始我們今天的學習之路
1.apply和call是什麼?
apply和call是function物件中的兩個方法。
2.什麼場景下面我們需要使用到apply和call?
舉個例子我們有兩個物件A和B,在物件A中有一個方法C,A物件經常使用方法C,B偶爾會使用到方法C,此時為了節約資源,減少冗餘程式碼我們不會在B中在寫一個方法C,而是直接使用B呼叫A中的方法C,在這樣的場景下面我們就會使用到apply和call。
3.apply和call的定義?
從我們的第二個問題我們可以大概知道,apply和call就是改變當前物件的作用域,B能夠訪問A中的方法C,在這裡我們稱作B改變了A中的this指向,相當於將A物件中函式C的上下文修改為B。
官方的定義:
apply:呼叫一個物件的一個方法,用另一個物件替換當前物件。例如:B.apply(A, arguments);即A物件呼叫B物件的方法。
call:呼叫一個物件的一個方法,用另一個物件替換當前物件。例如:B.call(A, args1,args2);即A物件呼叫B物件的方法。
從官方的定義我們能夠看出apply和call的唯一區別在於,他們的引數不同,apply接收兩個引數,第一個引數為要改變的原函式的上下文,第二個引數為替換原函式的引數,我們需要注意的是第二個引數必須是陣列。call可以接收多個引數,第一個引數是要改變的原函式的上下文,第二個引數和以後的引數為要替換原函式的引數
4.apply和call的實際使用
apply和call的實際使用我將通過舉例實戰的方式來講解
var A = { name: "AAA", fn: function(skill) { this.skill = skill; console.log("my name is " + this.name + ", my skills are " + this.skill); } } var B = { name: "BBB" } A.fn("sing"); //my name is AAA, my skills are sing B.fn("dance"); //Uncaught TypeError: B.fn is not a function;
在這段程式碼我們能夠看到B直接呼叫A中的fn是會報錯的,因為B中並沒有A中fn方法,接下來我們使用apply和call實現B能呼叫fn方法
var A = { name: "AAA", fn: function(skill) { this.skill = skill; console.log("my name is " + this.name + ", my skills are " + this.skill); } } var B = { name: "BBB" } A.fn("sing"); //my name is AAA, my skills are sing //B.fn("dance"); //Uncaught TypeError: B.fn is not a function; A.fn.apply(B,["dance"])//my name is BBB, my skills are dance A.fn.call(B,'dance21')//my name is BBB, my skills are dance21
在執行A物件的函式fn時,通過apply將函式fn的執行上下文(this)暫時修改為物件B,此時fn中的this指向物件B,同時修改原函式fn的引數為“dance”(注意“dance”引數必須是陣列的形式),call方法自動執行改變之後的原函式