当前位置:  开发笔记 > 编程语言 > 正文

使用JavaScript原型调用方法

如何解决《使用JavaScript原型调用方法》经验,为你挑选了4个好方法。

如果它被覆盖,是否可以从JavaScript中的原型方法调用基本方法?

MyClass = function(name){
    this.name = name;
    this.do = function() {
        //do somthing 
    }
};

MyClass.prototype.do = function() {  
    if (this.name === 'something') {
        //do something new
    } else {
        //CALL BASE METHOD
    }
};

Christoph.. 200

我不明白你究竟想要做什么,但通常实现特定于对象的行为是这样做的:

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

MyClass.prototype.doStuff = function() {
    // generic behaviour
}

var myObj = new MyClass('foo');

var myObjSpecial = new MyClass('bar');
myObjSpecial.doStuff = function() {
    // do specialised stuff
    // how to call the generic implementation:
    MyClass.prototype.doStuff.call(this /*, args...*/);
}

不要在JS中使用"Class"字样,因为它会造成混淆.JavaScript中没有类 (10认同)

我不明白为什么会有这么多的赞成票并被标记为正确.这仅覆盖基类的一个实例的行为,而不是所有子类的实例.因此,这不回答这个问题. (3认同)


小智.. 24

那么一种方法是保存基本方法,然后从override方法调用它,就像这样

MyClass.prototype._do_base = MyClass.prototype.do;
MyClass.prototype.do = function(){  

    if (this.name === 'something'){

        //do something new

    }else{
        return this._do_base();
    }

};

这将创建无限递归. (11认同)

@JohanTidén`_do_base`存储对之前定义的任何函数的引用.如果没有,那么它将是'未定义'.JavaScript不是`make`-表达式永远不会像你建议的那样被懒惰地评估.现在,如果原型继承自*也*使用_do_base来存储它认为是基本类型的`do`的实现,那么你确实遇到了问题.所以,是的,如果使用这种方法,闭包将是一种更好的,继承安全的方式来存储对原始函数实现的引用 - 尽管这需要使用`Function.prototype.call(this)`. (10认同)

我去过那里:无限递归. (3认同)


Magnar.. 16

我担心你的榜样不会像你想象的那样发挥作用.这部分:

this.do = function(){ /*do something*/ };

覆盖了.的定义

MyClass.prototype.do = function(){ /*do something else*/ };

由于新创建的对象已经具有"do"属性,因此它不会查找原型链.

Javascript中经典的继承形式很笨拙,难以掌握.我建议使用Douglas Crockfords简单的继承模式.像这样:

function my_class(name) {
    return {
        name: name,
        do: function () { /* do something */ }
    };
}

function my_child(name) {
    var me = my_class(name);
    var base_do = me.do;
    me.do = function () {
        if (this.name === 'something'){
            //do something new
        } else {
            base_do.call(me);
        }
    }
    return me;
}

var o = my_child("something");
o.do(); // does something new

var u = my_child("something else");
u.do(); // uses base function

在我看来,在javascript中处理对象,构造函数和继承的更清晰的方法.你可以在Crockfords Javascript中阅读更多内容:好的部分.



1> Christoph..:

我不明白你究竟想要做什么,但通常实现特定于对象的行为是这样做的:

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

MyClass.prototype.doStuff = function() {
    // generic behaviour
}

var myObj = new MyClass('foo');

var myObjSpecial = new MyClass('bar');
myObjSpecial.doStuff = function() {
    // do specialised stuff
    // how to call the generic implementation:
    MyClass.prototype.doStuff.call(this /*, args...*/);
}


不要在JS中使用"Class"字样,因为它会造成混淆.JavaScript中没有类
我不明白为什么会有这么多的赞成票并被标记为正确.这仅覆盖基类的一个实例的行为,而不是所有子类的实例.因此,这不回答这个问题.

2> 小智..:

那么一种方法是保存基本方法,然后从override方法调用它,就像这样

MyClass.prototype._do_base = MyClass.prototype.do;
MyClass.prototype.do = function(){  

    if (this.name === 'something'){

        //do something new

    }else{
        return this._do_base();
    }

};


这将创建无限递归.
@JohanTidén`_do_base`存储对之前定义的任何函数的引用.如果没有,那么它将是'未定义'.JavaScript不是`make`-表达式永远不会像你建议的那样被懒惰地评估.现在,如果原型继承自*也*使用_do_base来存储它认为是基本类型的`do`的实现,那么你确实遇到了问题.所以,是的,如果使用这种方法,闭包将是一种更好的,继承安全的方式来存储对原始函数实现的引用 - 尽管这需要使用`Function.prototype.call(this)`.
我去过那里:无限递归.

3> Magnar..:

我担心你的榜样不会像你想象的那样发挥作用.这部分:

this.do = function(){ /*do something*/ };

覆盖了.的定义

MyClass.prototype.do = function(){ /*do something else*/ };

由于新创建的对象已经具有"do"属性,因此它不会查找原型链.

Javascript中经典的继承形式很笨拙,难以掌握.我建议使用Douglas Crockfords简单的继承模式.像这样:

function my_class(name) {
    return {
        name: name,
        do: function () { /* do something */ }
    };
}

function my_child(name) {
    var me = my_class(name);
    var base_do = me.do;
    me.do = function () {
        if (this.name === 'something'){
            //do something new
        } else {
            base_do.call(me);
        }
    }
    return me;
}

var o = my_child("something");
o.do(); // does something new

var u = my_child("something else");
u.do(); // uses base function

在我看来,在javascript中处理对象,构造函数和继承的更清晰的方法.你可以在Crockfords Javascript中阅读更多内容:好的部分.


确实非常好,但你不能真正将`base_do`称为函数,因为你在原来的`do`方法中失去了任何`this`绑定.因此,基本方法的设置有点复杂,特别是如果您想使用基础对象将其称为"this"而不是子对象.我会建议类似于`base_do.apply(me,arguments)`的东西.

4> pholly..:

我知道这篇文章来自4年前,但由于我的C#背景,我一直在寻找一种方法来调用基类,而不必指定类名,而是通过子类上的属性获取它.所以我对Christoph的答案唯一的改变就是

由此:

MyClass.prototype.doStuff.call(this /*, args...*/);

对此:

this.constructor.prototype.doStuff.call(this /*, args...*/);


不要这样做,`this.constructor`可能并不总是指向'MyClass`.
推荐阅读
无名有名我无名_593
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有