簡體   English   中英

javascript中使用IIFE的“ this”關鍵字

[英]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而附加的,實際上對於該語言完全沒有必要。 一些圖書館使用它,您沒有選擇的余地,但是我總是向人們咨詢,他們控制了它們后,根本就不會使用thisnew (這更加令人困惑)

JavaScript中的this關鍵字可以調用或執行函數。 在您的示例中,對於IIFE, this將是全局Window對象AKA window

您的問題似乎缺少代碼。 CarTruck是否應該擴展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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM