javascriptfunctionobjectecmascript-6hasownproperty

Why does hasOwnProperty behave differently for constructor functions and instances?


hasOwnProperty seems to behave differently depending on whether it is called on a constructor function or an instance, depending on the use of this or let for the contained members.

function Animal(_name) {

    let name = _name;

    this.getName = function() {
        return name;
    }

};

function Animal2(_name) {

    this.name = _name;

    let getName = function() {
        return name;
    }

}

let a = new Animal("greg");
let a2 = new Animal2("tim");

console.log(a.hasOwnProperty("name"));
console.log(a2.hasOwnProperty("name"));
console.log(Animal.hasOwnProperty("name"));
console.log(Animal2.hasOwnProperty("name"));
console.log("");
console.log(a.hasOwnProperty("getName"));
console.log(a2.hasOwnProperty("getName"));
console.log(Animal.hasOwnProperty("getName"));
console.log(Animal2.hasOwnProperty("getName"));

This outputs the following:

false
true
true
true

true
false
false
false

Why is this the case? I understand using "let" in a constructor function emulates 'private' members, which may explain why a.hasOwnProperty("name") and a2.hasOwnProperty("getName") both return false, but don't know why the constructor functions don't 'own' their methods.


Solution

  • Because Animal and Animal2 are constructor functions - and a function has a property name which is the name of the function. If you look at Animal.name or Animal2.name, you see that it's Animal and Animal2. And because neither Animal nor Animal2 have a property getName, only instances of Animal, the other three checks for getName return false.

    function Animal(_name) {
        let name = _name;
        this.getName = function() {
            return name;
        }
    };
    
    function Animal2(_name) {
        this.name = _name;
        let getName = function() {
            return name;
        }
    }
    console.log(Animal.name);
    console.log(Animal2.name;