【问题标题】:method for object's property in JavascriptJavascript中对象属性的方法
【发布时间】:2016-01-09 23:16:19
【问题描述】:

我有一个构造函数:

function Point(point, left, right) {
    this.p = point;
    this.l = left;
    this.r = right
}
var bezierPoint = new Point([0.0,0.0],[-50.43794, 0.0],[25.54714,4.78643])

有没有合适的方法来创建一个我可以在所有属性中使用而不是对象本身的方法? 例如如果我想输出

console.log(bezierPoint.l) // -50.43794, 0.0
console.log(bezierPoint.l.round()) // -50, 0
console.log(bezierPoint.r.round()) // 26, 5

或者这是错误的方法,我应该为我将使用的数据类型制定新的方法?类似的东西

Array.prototype.round = function() {
    return [Math.round(this[0]), Math.round(this[1])] //this code doesn't matter now
}
console.log(bezierPoint.l.round()) // -50, 0

【问题讨论】:

  • 你有不想使用prototype的原因吗?
  • 由于bezierPoint.l 似乎返回了一个数组,因此获得所需内容的唯一方法是添加到 Array 构造函数中,而您可能不应该这样做
  • 我更喜欢你改变point的原型而不是Array的原型。
  • 避免修补 Array 原型。也许希望将这些方法添加到您的 Point 构造函数中。一个例子是Point.getRounded,它将返回一个四舍五入的topleftrightbezierPoint.getRounded 返回[0,0], [-50, 0], [26, 5]
  • 因此,如果我理解正确,最好为 Point 添加一个方法,这将使用提供的属性来满足我的需要?类似bezierPoint.getRounded(p) 而不是 'bezierPoint.p.getRounded()'

标签: javascript object methods properties


【解决方案1】:

您可以将参数用作内部变量并公开方法如下:

function Point(point, left, right) {

    function exposed(points) {
        return {
            value: function () {
                return points;
            },
            round: function () {
                return [Math.round(points[0]), Math.round(points[1])];
            }
        };
    }

    this.p = exposed(point);

    this.l = exposed(left);

    this.r = exposed(right);

}

然后你可以像这样使用它:

var bezierPoint = new Point([0.0, 0.0], [-50.43794, 0.0], [25.54714, 4.78643]);

document.write('value:' + bezierPoint.l.value() + '<br />'); // value:-50.43794,0

document.write('round:' + bezierPoint.l.round() + '<br />'); // round:-50,0

【讨论】:

  • 感谢您的回复,所以如果我想为每个属性(.p、.l 和 .r)使用 3 个相同的方法,我必须声明 3 个外观相同的函数?
  • 我已经编辑了答案,因此您可以使用一个通用函数来公开您想要的所有方法。但是请记住,这只是其中一种可能的方法,@paul 的解决方案同样有效。
【解决方案2】:

另一种方法。更多代码,但更多原型和可靠。

// Common point class

/**
 * Creates simple point class
 * Point can be passed as two separate coordinates or as an array (coordinates pair). In case of array, second argument is omitted.
 * @param {String|Number|Array} a
 * @param {String|Number|undefined} b
 * @returns {Point}
 */
var Point = function (a, b) {
    if (!!a && !!b) {
        this.a = parseFloat(a);
        this.b = parseFloat(b);
    } else if (a.constructor === Array ? a.length === 2 : false) {
        this.a = parseFloat(a[0]);
        this.b = parseFloat(a[1]);
    } else {
        throw 'Wrong data provided for `Point`';
    }
}

/**
 * @returns {Array} Rounded coordinates pair
 */
Point.prototype.round = function () {
    return [Math.round(this.a), Math.round(this.b)];
}

/**
 * @returns {Array} Raw coordinates pair (as they were passed to constructor)
 */
Point.prototype.value = function () {
    return [this.a, this.b];
}

// Bezier point class

/**
 * Creates a Bezier point instance
 * @param {Array|Point} point
 * @param {Array|Point} left
 * @param {Array|Point} right
 * @returns {BezierPoint}
 */
var BezierPoint = function (point, left, right) {
    this.p = point instanceof Point ? point : new Point(point);
    this.l = left instanceof Point ? left : new Point(left);
    this.r = right instanceof Point ? right : new Point(right);
}

// Operation

var bezierPoint = new BezierPoint([0.0,0.0], [-50.43794, 0.0], [25.54714,4.78643]);

每个点都可以作为数组传递给BezierPoint,也可以作为格式正确的Point 类。


UPD:作为对现有答案能力的扩展,可以提供下一种方式来定义任意点数。

var ArbitraryNumberOfPoints = function (args) {
    this.points = args.length === 0 ? [] :
        args.map(function (arg) {
            return arg instanceof Point ? arg : new Point(arg);
        });
}

ArbitraryNumberOfPoints.prototype.round = function () {
    return this.points.map(function (pointInstance) {
        return pointInstance.round();
    });
}   

【讨论】:

  • 但是这样我每个对象只能得到 2 个坐标,是吗?我想在一个 Point 对象中拥有所有 6 个坐标(点本身的 2 个坐标 + 2 个控制点的 2 个坐标)并在它们上使用 round() 方法,而不是在对象本身上
  • 这是您可以开始的一点。要使round 更具动态性,您可以使用Array.prototype.map()。为了使点更广泛,您可以使用数组来存储品脱(不将每个点分配给类中的单独变量),然后在此数组中的每个Point 上应用roundmap
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-01-07
  • 1970-01-01
  • 2021-08-07
  • 1970-01-01
  • 1970-01-01
  • 2016-07-18
  • 1970-01-01
相关资源
最近更新 更多