您好,登錄后才能下訂單哦!
this 的定義
表示當前執行代碼的環境對象
因此可將 this 的剖析分為“全局環境” 和 “函數環境” 兩種類型的環境對象
全局環境
console.log(this === window); // true var a = 10; console.log(this.a); // 10
函數環境
在函數內部,this 的取值取決于函數被調用時的運行環境。
這里涉及到內存里的數據結構相關的知識點,當我們定義以下字面量對象時會發生一系列的關聯關系
var obj = { name: 'Tom' };
javascript 引擎會先在內存中生成 { name: 'Tom' } 對象,接著再把這個對象的內存地址賦值給 obj 變量,所以 obj 變量保存的只是一個內存地址而已,如果要獲取 obj.name,javascript 引擎會先從 obj 變量中拿到內存地址,然后從該地址中獲取原始對象,再返回 name 屬性。
而屬性值為函數時,該函數會被保存在內存中,然后將該內存地址賦值給該屬性,因此該地址賦值給不同環境執行時它的作用域是不一樣的,而 this 對象就是指向函數當前的執行環境對象,執行環境是會在 Event Loop(事件循環)過程中變化的,因此 this 在函數環境下是屬于運行時的。
var name = 'Tom'; var obj = { name: 'Iceberg', say: function() { console.log('my name is ' + this.name); }, sub: { say: function() { console.log('my name is ' + this.name); } } }; obj.say(); // my name is Iceberg obj.sub.say() // my name is undefined; var say = obj.say; say(); // my name is Tom;
上面的例子說明 obj.say() 執行環境為 obj 對象,而 obj.sub.say() 的執行環境卻是 obj.sub 對象,而對于 obj.sub 來說并沒有 name 屬性,因此為 undefined;而 var say = obj.say; 則表示將 say 方法的內存地址賦值給全局變量,因此從全局變量 name 中取值。
運用場景
接下來從 this 在函數環境下的不同運用場景來剖析
事件回調函數
var handler = { nickname: 'anonymous', register: function() { console.log(this.nickname); } } $('#registerBtn').on('click', handler.register); // undefined
以上邏輯點擊觸發后輸出的是 undefined,因為函數被當做事件觸發的回調函數執行時,this 是指向該觸發事件對應的元素,如要 this 仍然以 handler 對象為執行環境,則可使用函數的 bind 方法進行執行環境對象的綁定操作。
$('#registerBtn').on('click', handler.register.bind(handler)); // anonymous
在 react 中經常需要在回調函數中調用 this.state、this.props,按照上面的分析,將當前環境對象 bind 到回調函數中即可。
如果是使用的箭頭函數定義回調函數即可無需 bind,因為箭頭函數中 this 就是對應定義時所在的對象。
構造函數
要理解 this 在構造函數中的邏輯就要理清楚構造函數在實例化過程中都發生了什么。
function A() { this.name = 'Tom'; this.age = 20; } var a = new A();
使用 new 命令實例化構造函數 A 的過程中會發生以下流程
bind
bind 方法將函數體中的 this 指向新對象并返回一個新函數
function A() { this.nickname = 'Tom'; this.say = function() { console.log(this.nickname); } } var b = { nickname: 'John' }; var a = new A(); var say = a.say; var say1 = a.say.bind(a); var say2 = a.say.bind(b); say(); // undefined say1(); // Tom say2(); // John
call & apply
call 方法是指 Function.prototype.call,因此每個函數都會具備 call 方法,fun.call(thisArg, arg1, arg2, ...),call 方法接收的第一個參數會替換原有的 this 指向的執行環境對象。
function A() { this.name = 'Tom'; this.sayName = function(){ console.log(this.name); }; } function B() { this.name = 'John'; } var a = new A(); a.sayName.call(new B()); // John
而 apply 方法與 call 的區別僅在于 call 接收參數列表而 apply 接收數組參數或者類數組對象(如函數的 arguments 對象)。
總結
由于 javascript 的 Event Loop 原理,決定了執行上下文會不斷變化,因此 this 對象誕生于表達當前的執行環境對象。
以上所述是小編給大家介紹的javascript的this關鍵字的用法詳解整合,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復大家的。在此也非常感謝大家對億速云網站的支持!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。