理解js中的call,js深入理解

本文目錄一覽:

在JS中,call()方法和apply()方法到底該怎麼應用?

1.apply與call是更改對象的內部指針,即改變對象的this指向的內容;

2.call與apply的第一個參數都是要傳入給當前對象的對象,及函數內部的this,後面的參數都是傳遞給當前對象的參數。

詳細用法如下:

1.call()

語法:obj1.call(obj2[,param1,param2,…]);

定義:用obj2對象來代替obj1,調用obj1的方法。即將obj1應用到obj2上;

說明:call 方法可以用來代替另一個對象調用一個方法,call 方法可將一個函數的對象上下文從初始的上下文改變為由 obj2 指定的新對象,如果沒有提供 obj2參數,那麼 Global 對象被用作 obj2。

2.apply()

語法:obj1.call(obj2[,arrArg]);

定義:用obj2對象來代替obj1,調用obj1的方法,即將obj1應用到obj2上,

說明:call ()和apply()作用一樣,但是call()可以接收任何類型的參數,而apply()只能接收數組參數。

3.基本用法

4.繼承特性

JS中關於call()方法的一個問題,如圖中所示,求高手詳解。

在分析這四種代碼前,首先得弄清楚,如果一個對象obj調用了f函數,這個obj會發生什麼樣的變化。

obj.f();

上面的代碼中對象obj調用了f函數,在f函數里,第一句是this.a = ‘A’。那麼這個this是指什麼?如果你不清楚,那我直接說好了。this就是只那個調用f函數的對象,顯然在這裡是obj。那麼this.a = ‘A’實際上就是obj.a = ‘A’,也就是說,obj多了一個屬性a,其值為A。同樣的道理,第二句代碼給obj添加了一個屬性b,其值是一個函數,alert出一個B。

明白了嗎?obj.f()的直接影響就是obj.a = ‘A’,obj.b = function(){alert(‘B’)}。

弄明白了obj.f()的影響,接下來要搞清楚的就是f.call(obj)是一種怎麼樣的調用。如果你了解call這個函數,你可以知道的更多些;如果你不了解,希望你自己去仔細研究下,我這裡只能直接告訴你:

f.call(obj)相當於obj.f()

看到了嗎,這就是為什麼要先講清楚obj.f()的影響。因為f.call(obj)其實就是obj.f()。

此時再來看這四種調用。

第一種:

首先來看看第一句,根據前面的分析,我們知道,此時e.a = ‘A’。那麼第二句幹了什麼呢?第二句alert(a),顯然這a和e是沒有關係的,由於變量a事先沒有定義,在js中不能直接使用未定義的變量,alert(a)其實出錯了,所以你沒有看到任何反應。但如果你使用開發者工具,就能看到,這樣的寫法已經報錯了。錯誤的代碼,自然沒有任何反應。

第二種:

第二種比較繞,還是來看看它的調用過程吧。f.call(e.t),這個e.t是什麼?因為e沒有t這個屬性,所以這句相當於f.call(undefined)。當call函數的第一個參數是undefined或者null時,f.call(undefined)就相當於f(),也相當於window.f()。那麼根據開頭的分析,這時f函數的調用者就是window了,也就是說window.a =’ A’了。第二句alert(a),顯然在函數e的作用域里,變量a是不存在的,所以js會到window的作用域去查找屬性a,而window的屬性a是有的,它的值是A,所以這個時候alert(a)就是alert(window.a),alert的結果就是A。

第三種:

我覺得看了前兩種調用的分析,你應該知道f.call(y.t)相當於什麼,它相當於y.t.f(),但遺憾的是,y這個變量並沒有定義,無論是在函數e的作用域內還是window的作用域內,y都是不存在的,而使用一個未定義的變量,是一種錯誤的語句,所以帶三種調用和第一種一樣,是錯了,alert(a)根本就沒有執行,因此沒有任何反應;當然,就算執行了alert(a)也是錯的,它和第一種調用的錯誤就一樣了。

第四種:

第四種應該是比較容易理解的了。根據開頭的分析,f.call(e),e.a = ‘A’,這個沒有意見吧?所以第二句alert(e.a)就alert出了A。

js中call和apply的區別

call 方法

調用一個對象的一個方法,以另一個對象替換當前對象。

call([thisObj[,arg1[, arg2[, [,.argN]]]]])

參數

thisObj

可選項。將被用作當前對象的對象。

arg1, arg2, , argN

可選項。將被傳遞方法參數序列。

說明

call 方法可以用來代替另一個對象調用一個方法。call 方法可將一個函數的對象上下文從初始的上下文改變為由 thisObj 指定的新對象。

如果沒有提供 thisObj 參數,那麼 Global 對象被用作 thisObj。

說明白一點其實就是更改對象的內部指針,即改變對象的this指向的內容。這在面向對象的js編程過程中有時是很有用的。

引用網上一個代碼段,運行後自然就明白其道理。

input type=”text” id=”myText” value=”input text”

script

function Obj(){this.value=”對象!”;}

var value=”global 變量”;

function Fun1(){alert(this.value);}

window.Fun1(); //global 變量

Fun1.call(window); //global 變量

Fun1.call(document.getElementById(‘myText’)); //input text

Fun1.call(new Obj()); //對象!

/script

call函數和apply方法的第一個參數都是要傳入給當前對象的對象,及函數內部的this。後面的參數都是傳遞給當前對象的參數。

運行如下代碼:

script

var func=new function(){this.a=”func”}

var myfunc=function(x){

var a=”myfunc”;

alert(this.a);

alert(x);

}

myfunc.call(func,”var”);

/script

可見分別彈出了func和var。到這裡就對call的每個參數的意義有所了解了。

對於apply和call兩者在作用上是相同的,但兩者在參數上有區別的。

對於第一個參數意義都一樣,但對第二個參數:

apply傳入的是一個參數數組,也就是將多個參數組合成為一個數組傳入,而call則作為call的參數傳入(從第二個參數開始)。

如 func.call(func1,var1,var2,var3)對應的apply寫法為:func.apply(func1,[var1,var2,var3])

同時使用apply的好處是可以直接將當前函數的arguments對象作為apply的第二個參數傳入

如何理解和熟練運用js中的call及apply

必須先理解this上下文是個什麼東西,這樣你才知道call、apply、bind是為了解決什麼問題才誕生的。 才能知道該怎麼使用它們。

《你不知道的JavaScript》上卷講的其中就包含this,你可以去看下, 這本書對於this的講解是最通俗易懂和最詳細的。

js中的call

java中對象包含屬性和方法, 方法即函數, 只有對象可以調用方法

但是js中一切皆對象, 函數是對象, 函數也可以調用方法

Function.prototype.call

Function.prototype.apply

Function.prototype.bind

Function.prototype.toString

為什麼js語言會在function原型上掛上這四個函數?

因為好處太多了, 現在我就說一說call的應用

再深入思考一下, call語法是基於什麼形成的呢 ?

了解底層語法有助於我們理解高級的語法

因為在底層的語法眼中, 高級語法只不過是工具, 根本不算語法, 不過是由我定義構建處理來的

理解call函數, 核心必要知識

哈哈哈, v8內部的不知道, 反正js基於現有語法就有這個能力 (還有解法, 基於 proto ,原型鏈的方式, var temp = Object.create(null)), 利用乾淨的地方, 防止覆蓋原對象的函數

顯然, 我們自己的上面的mycall還要很多問題

這裡我們就實現了自己的call, 以後看見call就知道都不過是些雕蟲小技了(當然真實的實現方式肯定需要考慮更多因素和性能, 而且在v8更大的環境下, 可能還不止一種實現方式,保持謙虛)

對於javascript 中的call函數的理解問題

標準解釋:call方法是將一個對象的方法在另一個對象的上下文環境中執行。

詳細解釋:你的例子中,myFun.call(myObject, 13, 3, 95)執行時是這樣的:

1. 調用myFun函數

2. 將13,3,95三個參數傳遞給它(你的myFun方法中沒有處理這些參數的代碼,所以傳了也沒有用)

3. 將myFun函數中的所有this用myObject代替(同樣,你的myFun函數中沒有使用this,所以執行結果和直接調用myFun()是一樣的)

修改一下你的例子,幫助你理解:

function myFun(p1, p2, p3)

{

this.para1 = p1;

this.para2 = p2;

this.para3 = p3;

}

var myObject = new Object();

alert(myObject.para1) //顯示undefined

myFun.call(myObject,13,3,95); /*執行的時候,myFun方法中的this全部用myObject對象代替,所以在這個例子中,執行myFun方法和直接寫下面的語句效果是一樣的:

myObject.para1 = 13;

myObject.para2 = 3;

myObject.para3 = 95;

*/

alert(myObject.para1) //顯示13

原創文章,作者:HONQC,如若轉載,請註明出處:https://www.506064.com/zh-hant/n/330924.html

(0)
打賞 微信掃一掃 微信掃一掃 支付寶掃一掃 支付寶掃一掃
HONQC的頭像HONQC
上一篇 2025-01-16 15:46
下一篇 2025-01-16 15:46

相關推薦

  • JS Proxy(array)用法介紹

    JS Proxy(array)可以說是ES6中非常重要的一個特性,它可以代理一個數組,監聽數據變化並進行攔截、處理。在實際開發中,使用Proxy(array)可以方便地實現數據的監…

    編程 2025-04-29
  • 解析js base64並轉成unit

    本文將從多個方面詳細介紹js中如何解析base64編碼並轉成unit格式。 一、base64編碼解析 在JavaScript中解析base64編碼可以使用atob()函數,它會將b…

    編程 2025-04-29
  • Node.js使用Body-Parser處理HTTP POST請求時,特殊字符無法返回的解決方法

    本文將解決Node.js使用Body-Parser處理HTTP POST請求時,特殊字符無法返回的問題。同時,給出一些相關示例代碼,以幫助讀者更好的理解並處理這個問題。 一、問題解…

    編程 2025-04-29
  • t3.js:一個全能的JavaScript動態文本替換工具

    t3.js是一個非常流行的JavaScript動態文本替換工具,它是一個輕量級庫,能夠很容易地實現文本內容的遞增、遞減、替換、切換以及其他各種操作。在本文中,我們將從多個方面探討t…

    編程 2025-04-28
  • JS圖片沿着SVG路徑移動實現方法

    本文將為大家詳細介紹如何使用JS實現圖片沿着SVG路徑移動的效果,包括路徑製作、路徑效果、以及實現代碼等內容。 一、路徑製作 路徑的製作,我們需要使用到SVG,SVG是可縮放矢量圖…

    編程 2025-04-27
  • 如何使用JS調用Python腳本

    本文將詳細介紹通過JS調用Python腳本的方法,包括使用Node.js、Python shell、child_process等三種方法,以及在Web應用中的應用。 一、使用Nod…

    編程 2025-04-27
  • 如何反混淆美團slider.js

    本文將從多個方面詳細闡述如何反混淆美團slider.js。在開始之前,需要明確的是,混淆是一種保護JavaScript代碼的方法,其目的是使代碼難以理解和修改。因此,在進行反混淆操…

    編程 2025-04-27
  • Python要學JS嗎?

    Python和JavaScript都是非常受歡迎的編程語言。然而,你可能會問,既然我已經學了Python,是不是也需要學一下JS呢?在本文中,我們將圍繞這個問題進行討論,並從多個角…

    編程 2025-04-27
  • 解決js ajax post 419問題

    對於使用ajax post請求時出現的419問題,我們需要進行以下幾個方面的闡述,包括返回碼的含義、可能出現的情況、解決方案等內容。 一、解析419返回碼 419返回碼錶示用戶超時…

    編程 2025-04-27
  • 深入解析Vue3 defineExpose

    Vue 3在開發過程中引入了新的API `defineExpose`。在以前的版本中,我們經常使用 `$attrs` 和` $listeners` 實現父組件與子組件之間的通信,但…

    編程 2025-04-25

發表回復

登錄後才能評論