gpt4 book ai didi

javascript - 在 JavaScript 中实现 Circle 构造函数,无需 ES6 类

转载 作者:行者123 更新时间:2023-12-03 01:21:49 26 4
gpt4 key购买 nike

Eric Faust 在以下有关 ES6 类的文章中输入了 Circle 构造函数:https://hacks.mozilla.org/2015/07/es6-in-depth-classes/

我想知道:

  1. 他为什么使用 defineProperty ?我们不能直接在构造函数中实现该行为吗?例如:Circle.draw = function draw() {..}
  2. 为什么使用 get/set而不仅仅是在正常属性中具有状态: Circle.circleCount
  3. 哪些属性应该直接在新实例对象上实现,通过this在构造函数中,vs on Constructor.prototype (考虑到两者如何使属性可用于新实例)?

埃里克的代码:

function Circle(radius) {
this.radius = radius;
Circle.circlesMade++;
}

Circle.draw = function draw(circle, canvas) { /* Canvas drawing code */ }

Object.defineProperty(Circle, "circlesMade", {
get: function() {
return !this._count ? 0 : this._count;
},

set: function(val) {
this._count = val;
}
});

Circle.prototype = {
area: function area() {
return Math.pow(this.radius, 2) * Math.PI;
}
};

Object.defineProperty(Circle.prototype, "radius", {
get: function() {
return this._radius;
},

set: function(radius) {
if (!Number.isInteger(radius))
throw new Error("Circle radius must be an integer.");
this._radius = radius;
}
});

let c1 = new Circle(10);
console.log(c1.area());
console.log(Circle.circlesMade);

我的版本:

function Circle(_radius) {
this.radius = _radius;

Circle.draw = function draw(circle, canvas) {
/* Canvas drawing code */
};

!Circle.circleCount ?
(Circle.circleCount = 1) //First construction
:
(Circle.circleCount = Circle.circleCount + 1);

this.area = function area() {
return Math.pow(this.radius, 2) * Math.PI;
};
}

let c1 = new Circle(10);
console.log(Circle.circleCount);
console.log(c1.area());

let c2 = new Circle(20);
console.log(Circle.circleCount);
console.log(c2.area());

最佳答案

我更喜欢将构造函数的原型(prototype)对象用于与实例共享的函数,而不是在每个实例上定义一个新函数。这可以节省内存,因为您只有该函数的一个实例,而不是为您创建的每个实例都有一个新副本。

您还可以在原型(prototype)上定义circleCount,因为所有实例都需要相同的数字。您只需要稍微小心地更改它,以确保不会在每个实例上创建隐藏属性。然后每个实例可以通过原型(prototype)链直接提供计数。

这样做会使函数变得复杂,但会简化其余代码:

function Circle(_radius) {
this.radius = _radius;
// creating an instance increments the count for everyone
Circle.prototype.circleCount++ // not this.circleCount++ which will create a new property on instance
}
Circle.prototype.draw = function draw(circle, canvas) {
/* Canvas drawing code */
};
Circle.prototype.area = function() {
return Math.pow(this.radius, 2) * Math.PI;
}
Circle.prototype.circleCount = 0


let c1 = new Circle(10);
console.log(c1.circleCount);
console.log(c1.area());

let c2 = new Circle(20);
console.log(c2.circleCount);
console.log(c2.area());

另外,关于Object.defineProperty的问题。看起来他正在使用它,这样他就可以设置 getter 和 setter 函数,而不仅仅是返回属性。您可以使用 area 来做到这一点,例如:

Object.defineProperty(Circle.prototype, "area", {
get: function() {
return Math.pow(this.radius, 2) * Math.PI;
}
});

这将允许您访问区域,就好像 ti 是每个实例上的属性一样:

c2.area // instead of a function c2.area()

您可以直接将面积设置为属性,但如果更改半径,则还需要更改面积。我想哪个最好取决于半径是否会改变。

关于javascript - 在 JavaScript 中实现 Circle 构造函数,无需 ES6 类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51732175/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com