带有新参数的Javascript继承

带有新参数的Javascript继承,javascript,class,object,inheritance,Javascript,Class,Object,Inheritance,[编辑:vector2d和vector3d不是很好的例子。我现在使用的是pt和ptMass。] 我一直在寻找答案,但似乎没有好的解决办法 假设我有一个对象,如下所示 function pt(x,y){ this.x = x; this.y = y; } function ptMass(x,y,m){ this.x = x; this.y = y; this.m = m; } 现在,我想要一个点质量,如下所示 function pt(x,y){

[编辑:
vector2d
vector3d
不是很好的例子。我现在使用的是
pt
ptMass
。]

我一直在寻找答案,但似乎没有好的解决办法

假设我有一个对象,如下所示

function pt(x,y){
    this.x = x;
    this.y = y;
}
function ptMass(x,y,m){
    this.x = x;
    this.y = y;
    this.m = m;
}
现在,我想要一个点质量,如下所示

function pt(x,y){
    this.x = x;
    this.y = y;
}
function ptMass(x,y,m){
    this.x = x;
    this.y = y;
    this.m = m;
}
最好使用继承来创建
ptMass

我目前正在使用以下方法来做这件事

function ptMass(x,y,m){
    pt.apply(this.arguments);
    this.m = m;
}
有没有办法用
原型实现这一点?
我试过以下方法,但不起作用

pt = function(m){this.m = m};
ptMass.prototype = new pt();

还有一个问题,使用原型继承的进展如何

首先,为什么继承它更好?
虽然我自己更喜欢组合(模块/组件和依赖项注入),但我有几个关于继承的参数

其次,您可以通过以下方式获得重用:

function Vector2D (x, y) {
    this.x = x;
    this.y = y;
}


function Vector3D (x, y, z) {
    Vector2D.call(this, x, y);
    this.z = z;
}
第三,在一个大规模的JS应用程序中,创建数以万计(或数百万)的多边形,额外的函数调用只会降低速度,这是不必要的

第四,你不能使用

Vector3D.prototype = new Vector2D();
首先,您没有将
x
y
初始化为矢量2D中的任何内容。
其次,
prototype
用于保存静态属性和函数,如果您来自其他语言

即使您确实初始化了
Vector2D
,对于Vector3D类的每个实例,它仍然是完全相同的Vector2D

为什么不只是:

var point2D = function (x, y) {
        return { x : x,
                 y : y  };
    },
    point3D = function (x, y, z) {
        return { x : x,
                 y : y,
                 z : z };
    };
…当您将这些特定的构建块作为基本元素时,是否可以组成使用它们的不同模块


编辑

这里的好处是您现在有了私有变量(
privateFunc
y
)。
缺点是在内存使用方面,对象的每个实例都需要有自己的私有方法副本。
因此,如果您正在创建成千上万个这样的对象(例如顶点/多边形),并且它们不需要
具有私有状态,那么这不是要使用的方法

但是,如果你正在制造玩家、敌人、控制器或任何你不想被篡改的东西,那么你确实想使用这样的方法(或更高级的方法)

如果您可能需要同样100%私有的静态数据/方法,那么您应该尝试以下格式:

var objectMaker = (function () {
    var staticData = 32,
        staticFunc = function (num) { return num + staticData; };

    return function (x, y) {
        var privateData = 12,
            privateMethod = function (num) {
                return y + privateData + staticFunc(num);
            };

        return { x : x,
                 method : function (num) { return privateMethod(num); }
        };
    };
}());


var myObj = objectMaker(3, 4);
myObj.x;          // 3;
myObj.method(12); // 12 + y(y === 4) + privateData + staticData;
因此,我们在这里所做的是,我们得到了一个立即触发函数(它在定义后立即触发,并将函数的值返回给变量)。
所以在我们的特殊情况下,这个函数立即返回我们想要用来创建新实例的实际函数

即时函数(不是我们返回的构造函数)中的私有变量和函数是静态的,因为您创建的每个实例都可以访问该闭包中完全相同的函数/数据。
缺点是这些静态函数不能访问私有(甚至是特定于实例的)数据。
这意味着您必须将值传递到静态函数中,并捕获来自静态函数的返回,因为您不能依赖静态方法来修改实例值(从技术上讲,如果将对象/数组传递到函数中,您可以直接修改它们,否则您必须捕获返回值)

现在,您可以拥有大量的助手函数,这些函数在实例之间共享(内存较低),同时仍然是私有的和安全的

如果您想要的是公共属性、公共方法和静态方法/属性,那么您可以这样访问它们:

var Obj = function (x, y) {
    this.x = x;
    this.per_instance_method = function () { return y; };
};

Obj.prototype.staticData = { z : 32 };
Obj.prototype.staticMethod = function () { return this.x + this.staticData.z; };

var myObj = new Obj(3, 4);
myObj.staticMethod();

…只是不要期望任何原型方法能够访问任何实例的私有数据(如
y
)。

不,您的第一个方法几乎是正确的:

function vector3d(x,y,z){
    vector2d.apply(this, arguments);
    // you might also use vector2d.apply(this, [].slice.call(arguments, 0,2));
    // or simpler vector2d.call(this, x, y);
    this.z=z;
}
因此,是的,您必须从构造函数调用它。调用它一次以创建原型对象将正确设置继承,但会创建一个
vector2D
的实例,您既不需要也不想要它。甚至可能造成伤害。请看一下有关的详细答案

有没有一种方法可以通过原型来实现这一点

将使原型对象从
vector3
的所有实例继承,从
vector2d
的原型对象继承。我不确定你是否需要,通常的二维方法都不会应用于三维向量

使用原型继承的进展是什么


我不喜欢您的方法,或者至少不喜欢您的具体示例,因为它违反了基本原则:“verctor 3d”不是“向量2d”。我想你要找的是参数化谢谢你,诺格卫士!我有一些后续问题。如果有一些方法用于
var point2D=function(x,y){..
,那么使用
var point2D=function(x,y){..
function point2D(x,y)有什么区别{…
?优点/缺点是什么?@user1863421查看一下编辑内容——希望这有帮助。请记住,这些解决方案都不是万能的。选择一个来满足您当时想要工厂的对象的需要。他们需要私有数据/方法吗?他们需要很多可以使用的辅助方法吗红色覆盖所有实例(需要访问私有数据)?还是只需要一些具有公共状态的简单对象,以及一些作用于该公共状态的静态方法?