簡體   English   中英

函數變量添加到全局范圍

[英]Function variable added to global scope

我宣布了這個功能:

function makePerson() {
    this.first = 'John';
    this.last = 'Oliver';
    fullName = function(){
        return this.first + this.last;
    }
}

沒有實例化它,但調用了這個函數。

makePerson()

現在,我可以訪問全局訪問中的firstlastfullName

有人能解釋我為什么會這樣。

注意:我沒有調用,而是實例化並檢查。 它不在全局范圍內,並且可以在函數/類/對象范圍內訪問。

這些是函數中this關鍵字的正常語義。 this可以通過多種方式進行評估,具體取決於您如何調用該函數。 假設我們有函數f ,其中body包含this關鍵字:

  1. f(a,b)標准函數調用語法) this被綁定到全局JavaScript Object ,這意味着如果你添加屬性到this函數體中,你實際上將它們添加到全球范圍。
  2. anObject.f(a,b) (方法調用語法)中, this綁定到anObject
  3. new f(a,b) (構造函數調用語法)中, this綁定到正在構造的對象。

this可能是一個混亂的來源,一旦函數體包含this ,函數就會停止成為一流的。 出於這個原因,我建議你盡量避免使用this道格拉斯克羅克福德也是如此

如果你想制作一個工廠功能(我強烈推薦上面的原因),你可以這樣做:

function makePerson() {
    var person = {
        first: 'John',
        last: 'Oliver'
    };
    person.fullName = function(){
        return person.first + person.last;
    };
    return person;
}

如果您仍想創建構造函數,則約定規定名稱必須大寫:

function Person() {
    this.first = 'John';
    this.last = 'Oliver';
    this.fullName = function(){
        return this.first + this.last;
    };
}

最后,使用this關鍵字有充分的理由,那就是原型繼承。 但是,我發現構造函數語法在這方面具有誤導性。 幸運的是,現在我們有了Object.create

var personPrototype = {
    fullName: function () {
        return this.first + this.last;
    }
};
function makePerson(first,last) {
    var person = Object.create(personPrototype);
    person.first = first;
    person.last = last;
    return person;
}

作為最后一個警告,這里有一個例子說明如何使用this會導致意外的約束和混淆:

var cn = makePerson("Chuck","Norris");
// works fine
console.log(cn.fullName());
// does not work, fullName is not a first-class function. You cannot detach it.
var fullName = cn.fullName;
console.log(fullName());

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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