最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

Javascript Prototype Chaining super class constructor and method calling - Stack Overflow

programmeradmin0浏览0评论

I'm a newbie in the JavaScript world, and I came up with this weird problem when i was attempting prototype chaining inheritence.

I have 3 classes

//class parent
function parent(param_1){
    this.param = param_1;
    this.getObjWithParam = function(val){
        console.log("value in parent class "+val);
        console.log("Constructor parameter : "+this.param);
    };

};

//class child
function child(param_1){
    this.constructor(param_1);
    this.getObjWithParam = function(val){
        console.log("value in child class "+val);
        val = Number(val)+1;
        child.prototype.getObjWithParam.call(this, [val]);
    };
};
child.prototype = new parent();

//class grandChild
function grandChild(param_1){
    this.constructor(param_1);
};
grandChild.prototype = new child();


var gc = new grandChild(666);
gc.getObjWithParam(0);

Firstly, I wanted to pass a parameter to the constructor of the parent classes, like the way they do by calling super(args) in other OO languages. so this.constructor(param_1); fairly suits the purpose.

However, the output es up as

value in parent class 0
Constructor parameter : 666

Which suggests, that the class grandChild has skipped the prototype chain, and instead of calling getObjWithParam() of child() class, has called getObjWithParam() of the parent class.

Does anyone have any idea what goes wrong here?

NB: 2 more findings i want to add, and the second one is the important one. --> If I try to find the constructor of grandChild class by

console.log(gc.constructor)

the output i get is

function parent(param_1){
    this.param = param_1;
    this.getObjWithParam = function(val){
        console.log("value in parent class "+val);
        console.log("Constructor parameter : "+this.param);
    };
}

which is the not quite the thing i expected. I was expecting to see the child class.

--> If I try to ment //this.constructor(param_1); in the child() and the grandChild() class, the code works exactly as expected.

Could anyone explain this phenomenon please.

Also, it'll be highly appreciated if anyone could suggest an workaround.

Thanks

I'm a newbie in the JavaScript world, and I came up with this weird problem when i was attempting prototype chaining inheritence.

I have 3 classes

//class parent
function parent(param_1){
    this.param = param_1;
    this.getObjWithParam = function(val){
        console.log("value in parent class "+val);
        console.log("Constructor parameter : "+this.param);
    };

};

//class child
function child(param_1){
    this.constructor(param_1);
    this.getObjWithParam = function(val){
        console.log("value in child class "+val);
        val = Number(val)+1;
        child.prototype.getObjWithParam.call(this, [val]);
    };
};
child.prototype = new parent();

//class grandChild
function grandChild(param_1){
    this.constructor(param_1);
};
grandChild.prototype = new child();


var gc = new grandChild(666);
gc.getObjWithParam(0);

Firstly, I wanted to pass a parameter to the constructor of the parent classes, like the way they do by calling super(args) in other OO languages. so this.constructor(param_1); fairly suits the purpose.

However, the output es up as

value in parent class 0
Constructor parameter : 666

Which suggests, that the class grandChild has skipped the prototype chain, and instead of calling getObjWithParam() of child() class, has called getObjWithParam() of the parent class.

Does anyone have any idea what goes wrong here?

NB: 2 more findings i want to add, and the second one is the important one. --> If I try to find the constructor of grandChild class by

console.log(gc.constructor)

the output i get is

function parent(param_1){
    this.param = param_1;
    this.getObjWithParam = function(val){
        console.log("value in parent class "+val);
        console.log("Constructor parameter : "+this.param);
    };
}

which is the not quite the thing i expected. I was expecting to see the child class.

--> If I try to ment //this.constructor(param_1); in the child() and the grandChild() class, the code works exactly as expected.

Could anyone explain this phenomenon please.

Also, it'll be highly appreciated if anyone could suggest an workaround.

Thanks

Share Improve this question edited Jan 2, 2012 at 12:59 clyfe 23.8k8 gold badges88 silver badges110 bronze badges asked Jan 2, 2012 at 12:56 TirthaTirtha 8721 gold badge12 silver badges29 bronze badges
Add a ment  | 

2 Answers 2

Reset to default 4

Declaring a this.SOME_METHOD in the constructor function doesn't add it to the type's prototype. Prototype functions need to be declared separately, e.g.:

//class parent
function parent(param_1){
    console.log("parent " + param_1);
    this.param = param_1;
}

parent.prototype.getObjWithParam = function(val) {
    console.log("value in parent class "+val);
    console.log("Constructor parameter : "+this.param);
};

//class child
function child(param_1){
    console.log("child " + param_1);
    this.constructor(param_1);
}
child.prototype = new parent();
child.prototype.getObjWithParam = function(val) {
    console.log("value in child class "+val);
    val = Number(val)+1;
    parent.prototype.getObjWithParam.call(this, [val]);    
}

//class grandChild
function grandChild(param_1){
    console.log("grandChild " + param_1);
    this.constructor(param_1);
}
grandChild.prototype = new child();


var gc = new grandChild(666);
gc.getObjWithParam(0);

I would remend you to read this article, to get a deeper insight how prototypes work in javascript.

If you want to do chaining (Fluent Interface) like in jQuery:

<div id="div"></div>

<script type="text/javascript">
function $(id) {
    if(this.$) return new $.init(id);
}

$.init = function(id) {
     if(typeof id == 'string') {
         this.id = document.getElementById(id);
     }
};

$.init.prototype = $.prototype = {
    constructor: $,
    css: function(value) {
        for(i in value) {
            this.id.style[i] = value[i];
        }
        return this;
    },
    mush : function() {
        var text = this.id.innerHTML;
        this.id.innerHTML = text.split('').join('--');
        return this;
    },
    text : function(a) {
        this.id.innerHTML = a;
        return this;
    }
};

$('div').text('FOO').mush().css({
        'color' : 'red',
        'textTransform' : 'uppercase'
});
</script>

See example

发布评论

评论列表(0)

  1. 暂无评论