JS ES6类语法和原型混乱

时间:2020-04-28 10:08:24

标签: javascript prototype

好的,据我所知,我们将像这样编写一个类构造函数

class User {
    constructor(name, age) {
        this.name = name;
        this.age = age;
    }

    //anything outside of constructor belong to this.prototype

    getName() {
        console.log(this.name);
    }
    getAge() {
        console.log(this.age);
    }
}

因此,如果我写这样的话:

class User {
    constructor(name, age) {
        this.name = name;
        this.age = age;
    }

    getName() {
        console.log(this.name);
    }
}

User.prototype.getAge = function () {
    console.log(this.age);
};

从技术上讲应该完全一样,对吧?还是我错了?因为当我尝试每个时,都会得到2个不同的结果:

let user = new User('john', 23);

let properties = [];

for (let prop in user) {
    properties.push(prop);
}

console.log(properties); //The first code result : ["name", "age"]
                         //The second code result : ["name", "age", "getAge"]

那么两者有什么区别?

3 个答案:

答案 0 :(得分:1)

两者之间的区别在于,使用User.prototype.getAge = ...将添加带有属性描述符enumerable: true的属性。这意味着它以for...in循环的形式显示。

for...in语句遍历对象的所有enumerable properties,这些对象由字符串键入(忽略由Symbol s键入的字符串),包括继承的可枚举属性

class User {
    constructor(name, age) {
        this.name = name;
        this.age = age;
    }

    getName() {
        console.log(this.name);
    }
}

User.prototype.getAge = function () {
    console.log(this.age);
};

let user = new User('john', 23);
let properties = [];

for (let prop in user) {
    properties.push(prop);
}

console.log(properties);

console.log(Object.getOwnPropertyDescriptor(User.prototype, "getName"));
console.log(Object.getOwnPropertyDescriptor(User.prototype, "getAge"));

如果要以完全相同的方式定义原型,则必须使用相同的属性描述符。这可以通过Object.defineProperty()来实现:

Object.defineProperty(User.prototype, "getAge", {
    value: function () {
        console.log(this.age);
    },
    writable: true,
    enumerable: false,
    configurable: true,
});

答案 1 :(得分:0)

类语法只是一个语法糖。

答案 2 :(得分:0)

在第二种情况下,您将添加一个名为getAge的属性。它的类型是函数。