[英]the 'this' key word with IIFE in javascript
我正在從其中一本書的示例中練習Java腳本,遇到了以下問題
代碼一 :在這里,我了解到javascript中的“ this”關鍵字引用了擁有“ this”關鍵字所在代碼的對象。
function Vehicle1(theYear, theMake, theModel) {
var year = theYear;
var make = theMake;
var model = theModel;
this.getYear = function () { return year; };
this.getMake = function () { return make; };
this.getModel = function () { return model; };
}
Vehicle1.prototype.getInfo = function () {
return 'Vehicle1: ' + this.getYear() + ' ' + this.getMake() + ' ' + this.getModel();
}
代碼二 :在這里,我正在學習使用IIFE(立即調用函數表達式)創建命名空間的方法。
(function () {
this.myApp = this.myApp || {};
var ns = this.myApp;
var vehicleCount = 5;
var vehicles = new Array();
ns.Car = function () { };
ns.Truck = function () { };
var repair = {
description: 'changed spark plugs',
cost: 100
};
} ());
我應該單獨執行上述代碼,以了解作者試圖解釋的概念。 但是我最終在單個文件中執行了這兩個代碼,並且我在代碼一中得到了錯誤消息,指出
未捕獲的TypeError:未定義不是函數Vehicle1.getInfo.myApp
問題是:為什么或如何IIFE函數試圖在代碼1中放置或找到myApp名稱空間?
如果我分別執行以上2條代碼,則所有工作都按預期進行。
編輯這里是完整的代碼,只需使用腳本標簽將其復制到html的頭部。 我在chrome中運行它,並在控制台中查找錯誤詳細信息
function Vehicle1(theYear, theMake, theModel) {
var year = theYear;
var make = theMake;
var model = theModel;
this.getYear = function () { return year; };
this.getMake = function () { return make; };
this.getModel = function () { return model; };
};
Vehicle1.prototype.getInfo = function () {
return 'Vehicle1: ' + this.getYear() + ' ' + this.getMake() + ' ' + this.getModel();
}
(function () {
this.myApp = this.myApp || {};
var ns = this.myApp;
var vehicleCount = 5;
var vehicles = new Array();
ns.Car = function () { };
ns.Truck = function () { };
var repair = {
description: 'changed spark plugs',
cost: 100
};
} ());
我了解到javascript中的“ this”關鍵字引用了擁有“ this”關鍵字所在代碼的對象。
事實並非如此,但似乎有點像。
警告-以下內容聽起來很愚蠢。 那是因為javascript this
是一個非常糟糕的語言功能(人們應該停止使用它)。
這里的交易-有沒有真正這樣的事this
。 至少不是您認為的那樣。 就像其他參數一樣,它實際上是一個函數參數。
讓我演示給你看。
假設您有這樣的功能
function sayHi(firstName, lastName) {
console.log("Hi", firstName, " ", lastName);
}
這是兩種不同但幾乎相同的調用方法:
sayHi("Fred", "Flintstone");
sayHi.call(null, "Fred", "Flintstone");
這是因為所有函數都有call
方法。 如果願意,可以使用.call
編寫所有函數調用。
但是第一個null
參數是什么? 嗯,這參數是什么this
將設置為。 因此,如果您有:
function sayHi(lastName) {
console.log("Hi", this, " ", lastName);
}
你可以說
sayHi.call("Fred", "Flintstone");
現在讓我問一個問題。 如果你能使用總是寫的所有功能.call
,如果.call
采取this
作為一個參數旁邊的人,究竟是this
從任何其他參數有什么不同? 只是一個您不願透露姓名的人。
但是sayHi(...)
格式this
有何作用? 由於我們沒有直接指定,因此它一定來自某個地方。 嗯,在這種形式下-實際上只是一個call
的外觀-javascript 會猜測您希望它是什么。 規則並不是很復雜,但是仍然很混亂。
如果您將其作為對象調用
var fred = "Fred";
fred.sayHi = sayHi;
fred.sayHi("Flintstone");
相當於
fred.sayHi.call(fred, "Flintstone");
如果直接調用它:
sayHi("Flintstone");
規則規定它將猜測this
是全局window
對象。 除非您處於嚴格模式,否則這種情況將是undefined
(我認為它可能為null
)。
sayHi.call(window, "Flintstone");
IIFE就是這樣。
基本上, this
功能是為了使它看起來更像Java而附加的,實際上對於該語言完全沒有必要。 一些圖書館使用它,您沒有選擇的余地,但是我總是向人們咨詢,他們控制了它們后,根本就不會使用this
或new
(這更加令人困惑) 。
JavaScript中的this
關鍵字可以調用或執行函數。 在您的示例中,對於IIFE, this
將是全局Window
對象AKA window
您的問題似乎缺少代碼。 Car
和Truck
是否應該擴展Vehicle1
或其他?
而且您沒有調用Vehicle1.getInfo.myApp
代碼,因此我不確定如何獲取該消息。
由於第一個代碼之后缺少分號,導致出現錯誤,從而導致組合文件的解釋方式與預期的方式完全不同。
讓我們簡化代碼以查看結構。 你有類似的東西:
getInfo = function () {
this.getYear();
}
(function () {
this.myApp = {};
} ());
在第一個函數之后沒有分號,第二個函數周圍的括號被視為給出調用第一個函數的參數:
getInfo = function () {
this.getYear();
}(function () {
this.myApp = {};
} ());
因此,基本上就像您寫的那樣:
function getInfo() {
this.getYear();
}
getInfo(function () {
this.myApp = {};
}());
this
在這兩種情況下指的是Window
(或全局對象),因為功能不被稱為上的一個實例。 您正在調用第二個函數,該函數將設置Window.myApp
,然后將其返回值(未定義)傳遞給getInfo
。 getInfo
將訪問this.getYear
不存在的,所以你得到的錯誤類型。
我收到的錯誤以及您的原始代碼是:
TypeError:this.getYear不是一個函數
因為this
是全局對象,所以this.getYear
將是未定義的(不是函數)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.