0

对不起,我不能更好地表达这个。但我遇到了一些如下代码:

MyObject.prototype = Object.create(MyObject.prototype);
MyObject.prototype.constructor = MyObject;

而且我似乎无法弄清楚它的作用。MyObject 在它上面定义是这样的:

function MyObject(options) {
    this.someProp = someDefault;
    this.otherProp = process(options.something);
    // etc...
}

它总是被称为构造函数。我只是想知道前两行提供了什么好处,以及它是否是 Javascript 中的已知模式。

4

5 回答 5

2

我似乎无法弄清楚它的作用

MyObject.prototype它创建一个从 [旧] via继承的新对象,Object.create然后MyObject.prototype用它覆盖。它还显式添加了一个.constructor实际上应该已经存在的属性。

我只是想知道前两行提供了什么好处

没有,除非在该片段之前有人损坏了原型(如MyObject.prototype = Object.prototype),这是试图修复它。

…如果它是 Javascript 中的已知模式。

不是这样的。使用为构造函数定义的“类”之间Object.create的继承设置原型链是一种已知模式,但是构造函数在分配的每一侧都会不同。

于 2013-08-14T20:20:29.550 回答
1

我真的看不出这样做有什么好处。

它所做的是为新对象提供以前的对象方法。但它来自同一个物体......

这是一个很好的 JS 继承示例:

http://jsfiddle.net/aDCmA/2/

var App = (function(){
    var Being = function() {
        this.living = true;
        this.breathes = function () {
            return true;
        };
    };

    var Robert = function() {
        this.blogs = true;
        this.getsBored = function () {
            return "You betcha";
        }
    };
    Robert.prototype = new Being();

    return {
        Being: Being,
        Robert: Robert,
        being: function(){ return new Being(); },
        robert: function(){ return new Robert(); }
    }
}());

这是另一个类似的问题:从其他类继承原型方法而不覆盖自己的原型方法

感谢 Robert Nyman 最初写博客:http ://robertnyman.com/2008/10/06/javascript-inheritance-how-and-why/

于 2013-08-14T19:55:31.930 回答
1

让我们逐行查看:

MyObject.prototype = Object.create(MyObject.prototype);

这重新定义MyObject.prototype为一个继承自 的对象MyObject.prototype。这是不寻常的,因为从自身继承是没有意义的。

MyObject.prototype.constructor = MyObject;

由于上一行覆盖了MyObject.prototype,这只是修复了在此过程中丢失的构造函数属性。

我可以想到一个可能有用的场景:如果之前的一些代码搞砸了MyObject.prototype,例如将另一个构造函数的原型分配给它:

MyObject.prototype = SomethingElse.prototype; // wrong way to do inheritance.

然后您发布的代码将尝试修复它。

于 2013-08-14T20:20:39.867 回答
1

提供的两行代码似乎是使用原型继承的错误尝试,但我知道您将在哪里进行此操作以及您要完成的工作。

众所周知,JavaScript 中有两种方法可以定义具有属性和方法作为成员的对象——对象字面量表示法和函数表示法。使用对象字面量表示法,我们无法立即访问new关键字(将其想象为在 Java 或 C# 中使用抽象类)。使用函数表示法,我们可以访问new关键字,因为作为函数的对象的初始声明用作我们的构造函数。

在 ECMAScript 5 中,Object对象被赋予了一个名为的方法,该方法create为开发人员提供了一种简单的方法,可以从使用对象文字符号声明的现有对象创建新对象。(请参阅此处的文档)。但是,以函数表示法创建的对象在此方法中存在问题,因为它们是 Function 对象。该Object.create方法是使用简单继承的好方法,允许访问基本属性和方法。

使用函数表示法,一旦使用new关键字,结果就不是函数,而是对象。例如,我可以测试这个:

var Obj = function(){};
console.log(typeof Obj) // "function"

console.log(typeof new Object()); // "object"

因此,您只能继承一次(意味着子对象不能派生自):

var MyObject = new Object();
var anotherObj = new MyObject() // throws exception

为了缓解这个问题,您需要遵循三个步骤:

  1. 以函数表示法创建您的子对象(因此您可以使用new关键字创建它的新实例并从中继承)。
  2. 将子对象的原型(对象)设置为基础对象(也将是对象)的新实例的结果。
  3. 将子对象的构造函数(恰好在对象的原型上)设置回引用自身的函数(这是实例化之前的函数)。如果你不这样做,构造函数将仍然是一个对象,它不能产生新的实例。

从这里,您可以使用该模式创建子对象和父对象的新实例并从两者派生。这是一个实际的例子:

var Vehicle = function(){};
Vehicle.prototype.start = function() {
   return this.make + " " + this.model + " " + "started";
}

var Car = function(color, make, model) {
   this.color = color;
   this.make = make;
   this.model = model;
}
Car.prototype = new Vehicle();
Car.prototype.constructor = Car; 

var myCar = new Car("red", "chevy", "aveo");
myCar.start(); //"chevy aveo started"
于 2013-08-14T20:30:39.863 回答
0

这是完全有效的 Javascript。

任何 javascript 函数(例如Func)都可以用作构造函数,并且构造函数调用还需要一个prototype属性(即F.prototype或与函数关联的原型)。因此(几乎)每个函数都有一个原型属性。此属性的值(即Func.prototype)。

现在,与函数关联的这个原型的值是一个对象本身,它具有一个称为构造函数的单个不可枚举属性。而这个构造函数属性的值就是函数对象(即F自身)。

让我们举个例子。

说我构造一个函数Func

var 函数 = 函数() {
           //你的定义
          };

现在因为 this 可以作为构造函数调用,所以它必须有一个prototype属性Func.prototype让我们调用 this proto

原型 = Func.prototype;

现在原型有一个称为构造函数的属性(即不可枚举)。此构造函数的值等于函数对象本身。

不信我这样检查

Func.prototype.constructor === Func // =>true

任何函数都将始终返回true

现在从你解释的代码: 所以基本上这两行

MyObject.prototype = Object.create(MyObject.prototype);
MyObject.prototype.constructor = MyObject;

正在修改原型的值以具有MyObject定义的值的构造函数属性。但这无论如何都会在正常情况下发生。但原因可能是prototype对象的 可能已经从它继承的类中更早地更改了。在那种情况下,这两行是否有意义。

希望有帮助:)

于 2013-08-14T20:16:13.910 回答