摘要:在全局對象中調用,自然讀取的是全局對象的值構造器調用說明作為構造器調用時,指向返回的這個對象。最直觀的表現就是,去看一些優秀框架的源代碼時,不再是被繞的暈乎乎的。
學習起因:
在之前的JavaScript學習中,this,call,apply總是讓我感到迷惑,但是他們的運用又非常的廣泛。遂專門花了一天,來弄懂JavaScript的this,call,apply。
中途參考的書籍也很多,以《JavaScript設計模式與開發實踐》為主,《JavaScript高級程序設計》、《你不知道的JavaScript》為輔。這三本書對我理解this,call,apply都起了很大的幫助。
首先,我們先講述this。
在《JavaScript設計模式與開發實踐》關于this的描述中,我認為有一句話切中了this的核心要點。那就是:
JavaScript的this總是指向一個對象
具體到實際應用中,this的指向又可以分為以下四種:
作為對象的方法調用
作為普通函數調用
構造器調用
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 , 12.作為普通函數調用
說明:作為普通函數調用時,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); // Lxxyx console.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); // ReturnOthersCall和Apply
Call和Apply的用途一樣。都是用來指定函數體內this的指向。
Call和Apply的區別Call:第一個參數為this的指向,要傳給函數的參數得一個一個的輸入。
Apply:第一個參數為this的指向,第二個參數為數組,一次性把所有參數傳入。
如果第一個參數為null,則this指向宿主環境,在瀏覽器中則是window。(多謝評論中一波不是一波的指正)
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指向window func.apply(obj) // "Lxxyx" 將this指向obj2.借用其它對象的方法
這兒,我們先以一個立即執行匿名函數做開頭:
(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方法在谷歌的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也不能落下。
前端路漫漫,且行且歌。
最后附上本人博客地址和原文鏈接,希望能與各位多多交流。
Lxxyx的前端樂園
原文鏈接:寒假前端學習(7)——學習JavaScript之this,call,apply
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/78587.html
摘要:的作用在中,方法和方法都是為了改變函數運行時上下文而存在的,換句話說就是為了改變函數體內部的指向。歡迎前端大牛糾正錯誤,如有錯誤我會及時改正。 寫在前面: 隔了很長時間了,也不知道寫點什么。最近一直在研究ES6,一直想寫出來的文章能對初學者或者是在學習JS路上有所幫助的。這就是我的初衷。 call、apply的作用 在JavaScript中,call()方法和apply()方法都是為了...
摘要:系統,扎實的語言基礎是一個優秀的前端工程師必須具備的。第一個參數為調用函數時的指向,隨后的參數則作為函數的參數并調用,也就是。和的區別只有一個,就是它只有兩個參數,而且第二個參數為調用函數時的參數構成的數組。 系統,扎實的 javascript 語言基礎是一個優秀的前端工程師必須具備的。在看了一些關于 call,apply,bind 的文章后,我還是打算寫下這篇總結,原因其實有好幾個。...
摘要:后續我將推出進階系列,一方面是一個監督自己學習的一個過程,另一方面也會給看到的童鞋一些啟發。第二步鏈接到原型中現在把構造函數和參數都打印出來了。 原文:https://zhehuaxuan.github.io/... 作者:zhehuaxuan 寫在前面的話 前端的入門相對簡單,相對于其他方向天花板可能會相對較低。但是在市場上一個優秀的前端依舊是很搶手的。能夠站在金字塔上的人往往寥寥...
摘要:另外,的綁定和函數聲明的位置沒有任何關系,之取決于函數的調用方式。請看下面代碼這樣,我們就可以在調用的時候強制把它的綁定到上綁定在傳統的面向類語言中,使用初始化類時會調用類中的構造函數。 關于this 上一章我們講了關于作用域和閉包的相關知識,現在開始新一輪的學習,那就是JavaScript中最復雜的機制之一---this關鍵字。它是一個很特別的關鍵字,被自動定義在所有函數的作用域中。...
摘要:函數的調用有以下幾種方式作為對象方法調用,作為函數調用,作為構造函數調用,和使用或調用。并且規范中說明,只有對象實現了方法。使用了回到上面作為構造函數調用第一步創建一個空的對象,。第二步鏈接該對象即設置該對象的構造函數到另一個對象,即。 在src/core/instance/index.js中 if (process.env.NODE_ENV !== production && !(t...
閱讀 1652·2021-08-13 15:03
閱讀 2082·2019-08-30 15:54
閱讀 3544·2019-08-26 10:30
閱讀 1020·2019-08-26 10:22
閱讀 2746·2019-08-23 14:42
閱讀 1809·2019-08-22 11:16
閱讀 1038·2019-08-21 18:33
閱讀 3159·2019-08-21 17:28