javascript - 向函数添加属性并设置其原型(prototype)

标签 javascript prototype

我必须处理以下代码:

function Vector(x, y) {
    this.x = x || 0;
    this.y = y || 0;
}

Vector.add = function(a, b) {
    return new Vector(a.x + b.x, a.y + b.y);
};

Vector.sub = function(a, b) {
    return new Vector(a.x - b.x, a.y - b.y);
};

Vector.scale = function(v, s) {
    return v.clone().scale(s);
};

Vector.random = function() {
    return new Vector(
        Math.random() * 2 - 1,
        Math.random() * 2 - 1
    );
};

Vector.prototype = {
    set: function(x, y) {
        if (typeof x === 'object') {
            y = x.y;
            x = x.x;
        }
        this.x = x || 0;
        this.y = y || 0;
        return this;
    },

    add: function(v) {
        this.x += v.x;
        this.y += v.y;
        return this;
    },

    sub: function(v) {
        this.x -= v.x;
        this.y -= v.y;
        return this;
    },

    scale: function(s) {
        this.x *= s;
        this.y *= s;
        return this;
    },

    length: function() {
        return Math.sqrt(this.x * this.x + this.y * this.y);
    },

    lengthSq: function() {
        return this.x * this.x + this.y * this.y;
    },

    normalize: function() {
        var m = Math.sqrt(this.x * this.x + this.y * this.y);
        if (m) {
            this.x /= m;
            this.y /= m;
        }
        return this;
    },

    angle: function() {
        return Math.atan2(this.y, this.x);
    },

    angleTo: function(v) {
        var dx = v.x - this.x,
            dy = v.y - this.y;
        return Math.atan2(dy, dx);
    },

    distanceTo: function(v) {
        var dx = v.x - this.x,
            dy = v.y - this.y;
        return Math.sqrt(dx * dx + dy * dy);
    },

    distanceToSq: function(v) {
        var dx = v.x - this.x,
            dy = v.y - this.y;
        return dx * dx + dy * dy;
    },

    lerp: function(v, t) {
        this.x += (v.x - this.x) * t;
        this.y += (v.y - this.y) * t;
        return this;
    },

    clone: function() {
        return new Vector(this.x, this.y);
    },

    toString: function() {
        return '(x:' + this.x + ', y:' + this.y + ')';
    }
};

这段代码有一个函数Vector,这个函数有一个附加的属性,即Vector.add。但是,下面几行是 Vector.prototype,然后又定义了 add

所以在这一点上我们有 VectorVector.addVector.prototype.add 我不太确定是什么调用这些时的区别。

为了完整引用,我尝试重做的代码来自 Gravity Points CodePen这样您就可以查看整个代码及其用法。

但是,对于主要使用 ECMAScript 6 的我来说,至少可以说这段代码看起来很奇怪。

最佳答案

有关静态方法与原型(prototype)方法的更多信息,您可以 read this answer here .不过在你的情况下:

静态调用 通过将两个向量相加返回一个新向量。 v1v2保持不变。

let v1 = new Vector(1, 1);
let v2 = new Vector(2, 2);
let v3 = Vector.add(v1, v2);

v1.toString(); // (x:1, y:1)
v2.toString(); // (x:2, y:2)
v3.toString(); // (x:3, y:3)

原型(prototype)调用 将两个向量相加但不创建新的向量;相反,v2xy 属性被添加到 v1 上。

let v1 = new Vector(1, 1);
let v2 = new Vector(2, 2);
v1.add(v2);

v1.toString(); // (x:3, y:3)
v2.toString(); // (x:2, y:2)

请注意,原型(prototype)方法返回对调用它的实例的引用,因此可以链接后续调用:

v1.add(v2).sub(v3).add(v4).toString();

关于javascript - 向函数添加属性并设置其原型(prototype),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50101223/

相关文章:

python - 实现原型(prototype)或实例化类对象

javascript - 在循环中创建命名的 javascript 对象

ES6 中的 JavaScript 原型(prototype)模式

JavaScript 继承问题

javascript - 为什么 Chrome 会将引用类型为 Date 的对象的原型(prototype)视为 "Object {}",而不是 "Date {}"?

javascript - 刷新或提交表单后显示页面的特定部分

javascript - 使用 PHP 更改 URL,而不删除现有变量

javascript - Chrome 调试器不会迭代 _.each 循环

javascript - Firefox 扩展 - 面板元素 onclick 被覆盖

javascript - 除非指定 'write' 选项,否则计算错误 : Cannot write a value to a ko.。如果你想读取当前值,不要传递任何参数