摘要:由于匿名函數的作用域是全局性的,因此閉包的通常指向全局對象調用返回值為而不是我們預期的,在閉包中函數作為某個對象的方法調用時,要特別注意,該方法內部匿名函數的指向的是全局變量。
有人的地方就有江湖,有函數的地方就有this。而this在不同的環境下,又表現為不同的形式,難免讓人有種此this非彼this的疑惑
在java等面向對象的語言中,this指的就是當前對象,而在javascript中這就不靈了,javascript中this是在編譯期動態綁定的,這就形成了一把雙刃劍:足夠靈活卻又容易讓人迷惑。在javascript中this可以是全局對象、當前對象甚至任意對象(obj.call(this))。
我們通過函數的幾種不同調用方式來看一下各自this的意義:
在javascript中函數也是個對象,因此,函數可以作為一個對象的屬性出現:
var object = { name:"jeffie", sayWhat:function(){ console.log(this.name + ":hello"); //jeffie:hello } } object.sayWhat();
此處的this指向object對象,也就是函數所在的對象。
作為函數調用當函數直接被調用時,此時函數中的this指向全局變量,也就是window對象:
function obj(){ console.log(this); } obj();//Window構造函數中的this
在作為構造函數調用時,this指向的是新生成的實例對象:
function Plugin(name,type){ this.name = name; this.type = type; } var plugin = new Plugin("core",1); console.log(plugin.name);//core使用apply或者call調用
javascript中每個函數都包含兩個方法:apply()和call(),這兩個方法非常強大,它們可以切換函數的上下文執行環境,也就是說可以修改this綁定的對象。簡單來說,這兩個方法可以用來設置函數的this,兩個方法都接收兩個參數,第一個參數是運行函數的作用域,第二個參數是參數對象,唯一的區別是apply第二個參數為參數數組(Array或者arguments):
function Plugin(name,type){ this.name = name; this.type = type; this.debugs = function(name,type){ console.log(this); //Object {name: "base", type: 3} } } var plugin1 = new Plugin("core",1); var plugin2 = {name:"base",type:3}; console.log(plugin1.debugs.call(plugin2));
通過上面的示例可以看出this值不再指向Plugin對象了,而是指向了plugin2的對象。
閉包中使用this通常我們理解this對象是運行時基于函數綁定的,全局函數中this對象就是window對象,而當函數作為對象中的一個方法調用時,this等于這個對象。由于匿名函數的作用域是全局性的,因此閉包的this通常指向全局對象window:
var scope = "global"; var object = { scope:"local", getScope:function(){ return function(){ return this.scope; } } }
調用object.getScope()()返回值為global而不是我們預期的local,在閉包中函數作為某個對象的方法調用時,要特別注意,該方法內部匿名函數的this指向的是全局變量。參考上一篇閉包
這屬于 JavaScript 的設計缺陷,正確的設計方式是內部函數的 this 應該綁定到其外層函數對應的對象上,為了規避這一設計缺陷,聰明的 JavaScript 程序員想出了變量替代的方法,只需要把外部函數作用域的this存放到一個閉包能訪問的變量里面即可,約定俗成,該變量一般被命名為 that:
var scope = "global"; var object = { scope:"local", getScope:function(){ var that = this; return function(){ return that.scope; } } } object.getScope()()返回值為local。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/87605.html
摘要:下面是用實現轉成抽象語法樹如下還支持繼承以下是轉換結果最終的結果還是代碼,其中包含庫中的一些函數。可以使用新的易于使用的類定義,但是它仍然會創建構造函數和分配原型。 這是專門探索 JavaScript 及其所構建的組件的系列文章的第 15 篇。 想閱讀更多優質文章請猛戳GitHub博客,一年百來篇優質文章等著你! 如果你錯過了前面的章節,可以在這里找到它們: JavaScript 是...
摘要:到底是什么函數被調用時的位置是動態的箭頭函數不在此范圍,因為它的是函數定義時的上下文,是靜態的判斷規則如果是在中調用,則為新創建的對象通過,調用,是之前定的對象第一個參數注意若第一個參數是,則執行第四條判斷規則在么某個上下文中調用,是該上下 this到底是什么? 函數被調用時的位置(是動態的!)(箭頭函數不在此范圍,因為它的this是函數定義時的上下文,是靜態的!) 判斷規則 1.如果...
摘要:插件開發前端掘金作者原文地址譯者插件是為應用添加全局功能的一種強大而且簡單的方式。提供了與使用掌控異步前端掘金教你使用在行代碼內優雅的實現文件分片斷點續傳。 Vue.js 插件開發 - 前端 - 掘金作者:Joshua Bemenderfer原文地址: creating-custom-plugins譯者:jeneser Vue.js插件是為應用添加全局功能的一種強大而且簡單的方式。插....
普通函數的this指向 簡單說說 首先,按照慣例,我們先舉個栗子: var bar = 2; function foo() { this.bar = 1; this.getBar = function() { console.log(this.bar); } } var test = new foo(); var getBar = test.getBar; test.getB...
摘要:將對象的屬性拷貝到了對象,合并成一個新的對象。而這種行為也是新增的標準。總結本章講解了對象字面量語法拓展,新增方法,允許重復的對象字面量屬性,自有枚舉屬性排序,增強對象原型,明確了方法的定義。但是,就算把全部新增的功能記住也不是難事。 變量功能被加強了、函數功能被加強了,那么作為JavaScript中最普遍的對象,不加強對得起觀眾嗎? 對象類別 在ES6中,對象分為下面幾種叫法。(不需...
閱讀 1517·2021-11-18 10:02
閱讀 1657·2021-09-04 16:40
閱讀 3171·2021-09-01 10:48
閱讀 874·2019-08-30 15:55
閱讀 1853·2019-08-30 15:55
閱讀 1365·2019-08-30 13:05
閱讀 3013·2019-08-30 12:52
閱讀 1624·2019-08-30 11:24