在构造函数中定义原型方法

时间:2011-08-19 00:05:00

标签: javascript prototype-programming

今天,我看到了一生中从未见过的JavaScript模式。我无法说出使用这种模式的目的。这对我来说似乎不对,但我想保守一点。这可能是我以前从未见过的一些很棒的模式。

function Dog() {
    Dog.prototype.bark = function () {
        alert('woof!');
    }

    this.bark = function () {
        Dog.prototype.bark();
    }

    this.bark();
}

首先,我不是没有理由在构造函数中创建方法(作为特权成员)的粉丝。每次创建实例时都会导致创建函数。其次,在这段代码片段中,它还调用了原型名称" Dog",而不是"这个"。这让我非常困惑。

任何人都知道它有什么好处吗?

谢谢! 格雷斯

2 个答案:

答案 0 :(得分:13)

出于很多原因,这是一个非常糟糕的主意。其中一些是:

  1. 在构造函数中向原型添加方法将导致每次实例化一个新Dog时替换所有实例的prototype方法。
  2. 致电Dog.prototype.bark()表示thisDog.prototype而不是Dog的实例,这可能会导致严重问题。
  3. this.bark = function () { Dog.prototype.bark(); }是一些严肃的WTF。因为this.bark已经评估了原型方法,因此不需要这样做。并且像这样调用它实际上会破坏自然this值,如#2中所述。
  4. 这应该是:

    function Dog() {
      this.makeSound();
    };
    
    Dog.prototype.bark = function() {
      alert('woof');
    };
    
    Dog.prototype.makeSound = function() {
      this.bark();
    };
    

    或者,根本没有原型:

    function Dog() {
      this.bark = function() {
        alert('woof');
      };
    
      this.makeSound = function() {
        this.bark();
      };
    
      this.makeSound();
    };
    

    我根本不相信你的这个片段。

答案 1 :(得分:3)

很抱歉非常迟到的回复,但是如果你真的想在构造函数中添加原型并且在创建新实例时没有重新创建原型,那么你可以这样做:

function Dog() {
    if (!Dog.prototype.bark) {
        Dog.prototype = function() {
            console.log('woof');
        }
    }

    this.bark();
}

我仍然可能不会使用这种方法,但我有一些跨实例,在处理第三方框架(狡猾的类型)时这个方法是一个选项。