Javascript:如何从父对象覆盖和包装方法?

时间:2013-12-24 08:21:11

标签: javascript oop

我打算

  • 使用方法o
  • 的对象work
  • o.work()
  • 之前打印“Hello”
  • o.work()
  • 之后打印“再见”
  • o.work()将由第三方调用

我的尝试

// sample library object
var o = {
     score: 5,
     work: function() {
                     console.log(this.score);
                }
};

// my code
var cons = function () {
     this.score = 10;
     this.work = function () {
          console. log("Hello");
           // how to call parent's work() ?
           // if I do this.prototype.work() -> prints 5
           // But parent's work should be called when this.score is 10
          console. log("Bye");
     };
 };
 cons.prototype = o;
 my_o = new cons();

 // my_o will be passed to 3rd party instead of o

简而言之

  • 我正在尝试修饰继承的方法。
  • 超级很容易,但JavaScript没有超级

他们说原型继承是超越的。

更新

  • work()使用this.score,它在继承后被覆盖。

更新2

  • 期望o.work()应打印5
  • 期望my_o.work()应打印10

5 个答案:

答案 0 :(得分:2)

这有点难看,但你可以致电cons.prototype.work;

var Cons = function () {
     this.work = function () {
         alert('Hello');
         cons.prototype.work.call(this); // <= here
         alert('Bye');
     };
 };

或更通用:

var Cons = function () {
     this.parentwork = arguments.callee.prototype.work;
     this.work = function () {
         alert('Hello');
         this.parentwork.call(this);
         alert('Bye');
     };
};

请参阅此jsFiddle

答案 1 :(得分:0)

您需要确切地知道您要调用的父级是谁,并直接调用它(使用this方法传递本地.call值)或者您需要使用OOP库以实现相当复杂的代码设计为代价来实现这些能力。

答案 2 :(得分:0)

不,你需要在构造函数中给do函数和原型中的do函数使用不同的名称。

在构造函数中创建的实例成员将遮挡原型

中定义的同名属性

看一下john resig book中的这张照片:

enter image description here

当我们通过将页面加载到浏览器来运行测试时,我们看到了测试 的通过!这表明在构造函数内创建的实例成员将被遮挡 原型中定义的同名属性。

初始化操作的优先级很重要,如下所示:

  • 1属性绑定到原型中的对象实例。
  • 2属性被添加到构造函数中的对象实例中。

答案 3 :(得分:0)

替换

 // how to call parent's work() ?

cons.prototype.work();

就这么简单:)

答案 4 :(得分:0)

想出来:

// sample library object
var o = {
     score: 5,
     work: function() {
                     console.log(this.score);
                }
};

// my code
var cons = function () {
     this.score = 10;
     this.parent = arguments.callee.prototype;
     this.work = function () {
          console. log("Hello");
           // this.prototype.work() // Doesn't work since 'this' is an object
           // objects don't contain a link to prototype.
           // ###### With direct reference to `cons` ###### //
           // cons.prototype.work(); // (No Context) -> prints 5
                    // OR
           cons.prototype.work.call(this); // (With 'this' context) -> prints 10
           // ###### Without direct reference to `cons` [ Preferred ] ###### //
           // this.parent.work(); // (No Context) -> prints 5
                    // OR
           this.parent.work.call(this); // (With 'this' context) -> prints 10
          console. log("Bye");
     };
 };
 cons.prototype = o;
 my_o = new cons();

 my_o.work();

期待已经

  • o.work()打印5
  • my_o.work()打印10