вопрос (ы) относительно итерации по экземпляру, созданному с помощью простого сценария наследования js от resig - PullRequest
2 голосов
/ 29 марта 2011

За последнюю неделю я пытался узнать как можно больше о наследовании js и наткнулся на простой скрипт наследования js Джона Резига. во время тестирования кода все шло нормально, пока я не попытался перебрать один из моих расширенных объектов. вот код:

var Person = Class.create({
    init : function(sex, devStage) {
        this.sex = sex;
        this.devStage = devStage || "newBorn";
    },
    Sex : function(val) {
        if (val) { this.sex = val }
        else { return this.sex; }
    },
    DevStage : function(val) {
        if (val) { this.devStage = val; }
        else { return this.devStage; }
    }
});
var person = new Person("male");

var Mike = Person.extend({
    init : function(sex, devStage, name, age) {
        this._super(sex, devStage);
        this.name = name;
        this.age = age;
    },
    DevStage : function(val) {
        if (val) { this._super(val); }
        else { return this._super(); }
    },
    Name : function(val) {
        if (val) { this.name = val; }
        else { return this.name; }
    },
    Age : function(val) {
        if (val) { this.age = val; }
        else { return this.age; }
    }
});

var mike = new Mike("male", "adult", "Mike", 38);

for (var k in mike) {
    if (mike.hasOwnProperty(k)) { console.log("mike.hasOwnProperty(k) = " + k); }
} //only "sex", "devStage", "name" and "age" show up as properties in firebug's console

Я ожидал, что свойства функции DevStage, Name и Age существуют на объекте mike, но кажется, что единственные свойства, которые попадают в экземпляры каждого объекта, это те, которые отправляются в функцию init , другие свойства находятся на прототипе объекта и работают нормально, я просто не могу найти их с помощью метода hasOwnProperty. Я прочитал почти все комментарии в блоге Ресига, где опубликован сценарий, но не смог найти ничего, связанного с этой проблемой.

мой вопрос: нормально это или нет? я могу видеть времена, когда это будет проблемой, если делать некоторые проверки свойств между объектами. это похоже на серьезное беспокойство с моей стороны? хотя я не новичок в js, я, конечно, не опытный профессионал, поэтому ЛЮБАЯ обратная связь о моей нынешней ситуации была бы очень признательна.

1 Ответ

1 голос
/ 29 марта 2011

Да, это нормально. Свойства DevStage, Name, Age и init прикреплены к Mike прототипу , на который новый объект mike просто указывает на - свойства не копируются при создании объекта с помощью new Mike().

Таким образом, mike не обладает такими свойствами, как "собственные свойства" - они доступны только при просмотре внутреннего свойства прототипа mike (что и делает механизм JS автоматически при доступе к свойствам: mike.DevStage). Некоторые движки JS, такие как Chrome, предоставляют это внутреннее свойство прототипа как __proto__, которое вы можете проверить.

Это описание того, как mike представляется внутри:

mike = {
    __proto__: { // Internal pointer to the prototype, for Mike
        init: function () {},
        DevStage: function () {},
        Name: function () {},
        Age: function () {},
        __proto__: { // The prototype's prototype, for Person
            init: function () {},
            Sex: function () {},
            DevStage: function () {}

            // Ultimately, the prototype will point to Object.prototype
            __proto__: {...}
        }
    },

    // Own properties
    name: ...,
    age: ...,
    sex: ...,
    devStage: ...
}

Если вы удалите условие if (mike.hasOwnProperty(k)) из цикла, то вы увидите и другие свойства.

...