JavaScript中的this,call,apply使用及區別詳解,javascriptapply

來源:互聯網
上載者:User

JavaScript中的this,call,apply使用及區別詳解,javascriptapply

學習起因:

在之前的JavaScript學習中,this,call,apply總是讓我感到迷惑,但是他們的運用又非常的廣泛。遂專門花了一天,來弄懂JavaScript的this,call,apply。

中途參考的書籍也很多,以《JavaScript設計模式與開發實踐》為主,《JavaScript進階程式設計》、《你不知道的JavaScript》為輔。這三本書對我理解this,call,apply都起了很大的協助。

this

首先,我們先講述this。

在《JavaScript設計模式與開發實踐》關於this的描述中,我認為有一句話切中了this的核心要點。那就是:

JavaScript的this總是指向一個對象
具體到實際應用中,this的指向又可以分為以下四種:

  1. 作為對象的方法調用
  2. 作為普通函數調用
  3. 構造器調用
  4. apply和call調用

接下來我們去剖析前3點,至於第4點的apply和call調用,會在call和apply部分詳細講解。

1.作為對象的方法調用

說明:作為對象方法調用時,this指向該對象。
舉例:

/** * 1.作為對象的方法調用 * * 作為對象方法調用時,this指向該對象。 */var obj = { a: 1, getA: function() {  console.log(this === obj);  console.log(this.a); }};obj.getA(); // true , 1

2.作為普通函數調用

說明:作為普通函數調用時,this總是指向全域對象(瀏覽器中是window)。
舉例:

/** * 2.作為普通函數調用 * * 不作為對象屬性調用時,this必須指向一個對象。那就是全域對象。 */window.name = 'globalName';var getName = function() { console.log(this.name);};getName(); // 'globalName'var myObject = { name: "ObjectName", getName: function() {  console.log(this.name) }};myObject.getName(); // 'ObjectName'// 這裡實質上是把function() {console.log(this.name)}// 這句話賦值給了theName。thisName在全域對象中調用,自然讀取的是全域對象的name值var theName = myObject.getName;theName(); // 'globalName'

3.構造器調用

說明:作為構造器調用時,this指向返回的這個對象。
舉例:

/** * 3.作為構造器調用 *  * 作為構造器調用時,this指向返回的這個對象。 */var myClass = function() { this.name = "Lxxyx";};var obj = new myClass();console.log(obj.name); // Lxxyxconsole.log(obj) // myClass {name: "Lxxyx"}

但是如果建構函式中手動指定了return其它對象,那麼this將不起作用。
如果return的是別的資料類型,則沒有問題。

var myClass = function() { this.name = "Lxxyx"; // 加入return時,則返回的是別的對象。this不起作用。 return {  name:"ReturnOthers" }};var obj = new myClass();console.log(obj.name); // ReturnOthers

4.Call和Apply

Call和Apply的用途一樣。都是用來指定函數體內this的指向。

Call和Apply的區別

Call:第一個參數為this的指向,要傳給函數的參數得一個一個的輸入。
Apply:第一個參數為this的指向,第二個參數為數組,一次性把所有參數傳入。

如果第一個參數為null,則this指向調用的本身。

1.改變this指向

說明:這是call和apply最常用的用途了。用於改變函數體內this的指向。
舉例:

var name = "GlobalName"var func = function() { console.log(this.name)};func(); // "GlobalName"var obj = { name: "Lxxyx", getName: function() {  console.log(this.name) }};obj.getName.apply(window) // "GlobalName" 將this指向windowfunc.apply(obj) // "Lxxyx" 將this指向obj

2.借用其它對象的方法

這兒,我們先以一個立即執行匿名函數做開頭:

(function(a, b) { console.log(arguments) // 1,2 // 調用Array的原型方法 Array.prototype.push.call(arguments, 3); console.log(arguments) // 1,2,3})(1,2)

函數具有arguments屬性,而arguments是一個類數組。
但是arguments是不能直接調用數組的方法的,所以我們要用call或者apply來調用Array對象的原型方法。
原理也很容易理解,比如剛才調用的是push方法,而push方法在Google的v8引擎中,原始碼是這樣的:

function ArrayPush() { var n = TO_UINT32(this.length); // 被push對象的長度 var m = % _ArgumentsLength(); // push的參數個數 for (var i = 0; i < m; i++) {  this[i + n] = % _Arguments(i); // 複製元素 } this.length = n + m; //修正length屬性 return this.length;}

它只與this有關,所以只要是類數組對象,都可以調用相關方法去處理。

這部分內容比較複雜,再加上自己水平也不太夠。所以推薦有條件的同學去購買相關書籍,或者等我的後續部落格文章。

感想

通過對這部分的學習,算是加深了對JavaScript的理解。最直觀的表現就是,去看一些優秀架構的原始碼時,不再是被this,call,apply,bind繞的暈乎乎的。還是很開心的~

下一段時間,準備深入探索一下日常學習和使用的CSS。畢竟JavaScript學了,HTML和CSS也不能落下。

您可能感興趣的文章:
  • JavaScript call apply使用 JavaScript對象的方法綁定到DOM事件後this指向問題
  • 簡單對比分析JavaScript中的apply,call與this的使用
  • Javascript技術痛點之apply,call與this之間的銜接

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.