Why do classes and functions behave differently in Javascript?

I realized that all classes are essentially functions, and all instances were essentially objects. But something embarrassed me.

//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));
Run code

Expected Observations:

  • typeof(AnimalClass)and typeof(AnimalFunc)come back function.
  • typeof(cat)and typeof(dog)both return object.

Unexpected observations:

  • If I do Object.keys(cat), I get ["name","sayname"].
  • But if I do Object.keys(dog), I get ["name"].

My question is: why am I not getting saynameas a key for an instance of the class? Why can I get it only for a function instance?

+4
source share
3 answers

, , Object.keys .

, , prototype. - , sayName , .

, :

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

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

, JS. .. " javascript", .

+4

name sayname

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')))
+3

, AnimalClass sayName AnimalClass, AnimalFunc sayName , (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

Where each instance of AnimalFunc has its own definition sayName, because it is overridden in the constructor for each instance:

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
Run code

Equivalent to your AnimalClass with function:

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

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

And the equivalent of your AnimalFunc with class:

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

Source: https://habr.com/ru/post/1695838/


All Articles