Добавление свойств к функциям, а также установка их прототипа - PullRequest
0 голосов
/ 30 апреля 2018

Я должен работать над следующим фрагментом кода:

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.

Итак, на данный момент у нас есть Vector с Vector.add и Vector.prototype.add, и я не совсем уверен, в чем разница при их вызове.

Для полной справки код, который я пытаюсь повторить, взят из Gravity Points CodePen , чтобы вы могли просматривать весь код, а также его использование.

Однако мне, как человеку, который в основном использовал ECMAScript 6, этот код выглядит очень странно, если не сказать больше.

Ответы [ 2 ]

0 голосов
/ 30 апреля 2018

Для получения дополнительной информации о методах static vs prototype вы можете прочитать этот ответ здесь . В вашем случае, хотя:

Статический вызов возвращает новый вектор путем добавления двух векторов вместе. v1 и v2 остаются без изменений.

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)

вызов прототипа добавляет два вектора вместе, но не создает новый вектор; вместо этого x и y свойства v2 добавляются на 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)

Обратите внимание, что метод-прототип возвращает ссылку на экземпляр, к которому он был вызван, поэтому последующие вызовы могут быть связаны:

v1.add(v2).sub(v3).add(v4).toString();
0 голосов
/ 30 апреля 2018

Это разница между функцией уровня класса и функцией экземпляра. Это означает, что вы должны иметь возможность использовать Vector.add без экземпляра, а другой с экземпляром.

...