簡體   English   中英

為什么Javascript中的類和函數表現不同?

[英]Why do classes and functions behave differently in Javascript?

我的理解是所有類本質上都是函數,所有實例都是對象。 但有些事讓我很困惑。

 //Take this for example: function AnimalFunc(name) { this.name = name; this.sayName = function() { console.log(this.name); } } //And compare it with this: class AnimalClass { constructor(name) { this.name = name; } sayName() { console.log(this.name); } } //Now I instantiate them. cat = new AnimalFunc("cat") cat.sayName() // -> "cat" dog = new AnimalClass("dog") dog.sayName() // -> "dog" console.log(Object.keys(cat)); console.log(Object.keys(dog)); 

預期觀察:

  1. typeof(AnimalClass)typeof(AnimalFunc)都返回function
  2. typeof(cat)typeof(dog)都返回object

意外觀察:

  1. 如果我做Object.keys(cat) ,我會得到["name","sayname"]
  2. 但如果我做Object.keys(dog) ,我得到["name"]

我的問題是:為什么我沒有將sayname作為類實例的鍵? 為什么我只為函數實例獲取它?

第一個示例帶有一個函數,在創建實例時會創建一個新的函數屬性,因此會為Object.keys提取一個新的鍵。

第二個示例使用類將函數屬性分配給對象的prototype 因此,實際上並沒有創建新密鑰,並且可以通過走向原型鏈找到sayName函數。

您可以通過執行以下操作來復制類行為:

function AnimalFunc(name) {
  this.name = name
}

AnimalFunc.prototype.sayName = function () {
  console.log(this.name)
}

如果您想熟悉JS的原型模型,可以閱讀以下內容。 如果你願意,可以通過搜索“javascript原型”找到更多的文章等。

因為您已聲明了兩個名為namesayname屬性

this.name;
this.sayname;

在類AnimalClass您只將屬性聲明為構造函數體中的鍵name

this.name = ....

Object.keys()返回一個數組,其元素是與直接在對象上找到的可枚舉屬性相對應的字符串。 屬性的順序與手動循環對象的屬性所給出的順序相同。

所以,基本上會直接返回屬性使用上下文聲明this

類的示例

  • 聲明構造函數體內的函數

 class AnimalClass { constructor(name) { this.name = name; // This is just to illustrate! this.sayName = function() { console.log(this.name); } } } console.log(Object.keys(new AnimalClass('Dog'))) 

這是因為AnimalClasssayNameAnimalClass的原型中,而AnimalFuncsayName不是,它是實例的一部分( this )。

AnimalClass的情況下,只有一個sayName函數,所有實例共享對以下內容的引用:

 class AnimalClass { constructor(name) { this.name = name; } sayName() { console.log(this.name); } } var a = new AnimalClass("a"), b = new AnimalClass("b"); a.sayName === b.sayName; // true 

每個AnimalFunc實例都有自己的sayName定義,因為它在構造函數中為每個實例重新定義:

 function AnimalFunc(name) { this.name = name; this.sayname = function() { console.log(this.name); } } var a = new AnimalFunc("a"), b = new AnimalFunc("b"); a.sayName === b.sayName; // false 

使用function的AnimalClass的等價是:

function AnimalFunc(name) {
    this.name = name;
}

AnimalFunc.prototype.sayname = function() {
    console.log(this.name);
}

而使用classAnimalFunc相當於:

class AnimalClass {
    constructor(name) {
        this.name = name;
        this.sayName = function() {
            console.log(this.name);
        }
    }
}

暫無
暫無

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

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