这比。原型

IT技术 javascript prototype
2021-02-27 19:43:39

将方法“area”定义为“this”而不是“prototype”的属性有什么区别?

//console.clear()

function Rectangle(w, h) 
{
    this.width = w;
    this.height = h;
    this.area = function( ) { return this.width * this.height; }
}


var r = new Rectangle(2, 3);
var a = r.area( );

//console.log(a)

function Square(s) 
{
    this.side= s;
}

Square.prototype.area = function(){return this.side * this.side; }

var r = new Square(2);
var a = r.area( );

//console.log(a)

JavaScript - The definitive guide一节Prototypes and InheritanceChapter 9 , part 1,作者说,界定方法“区域”的原型对象里面是有益的,但他的解释并没有真正理解:

“..每个 Rectangle 对象的面积总是指同一个函数(当然,有人可能会改变它,但您通常希望对象的方法是常量)。对具有以下特性的方法使用常规属性是低效的旨在由同一类的所有对象共享(即使用相同构造函数创建的所有对象)。”

我知道这个问题看起来几乎像这样一个,但事实并非如此。

1个回答

定义函数whatever = function() { ... }往往会创建所谓的“闭包”,函数可以在其中访问定义它的函数的局部变量。当您说 时this.fn = function() { ... },每个对象都会获得该函数的一个实例(以及一个新的闭包)。这通常用于在 Javascript 中创建“私有”变量,但需要付出代价:每个函数(在每个对象中)都是不同的,并且占用更多内存。

当您说 时Rectangle.prototype.fn = function() { ... },所有Rectangles共享该函数的一个实例这可以节省内存,并且可以最大限度地减少浏览器中处理闭包不好的一些内存泄漏。如果您不需要“私有”成员或其他对定义函数的局部变量的访问,这通常是一个更好的主意。

@ide:谢谢你们的解释!另外,你能告诉我在哪里可以了解更多关于这方面的信息吗?
2021-04-29 19:43:39
从技术上讲, function() {...} 总是创建一个闭包,不管它被分配给什么。其他一切看起来都很棒!
2021-04-30 19:43:39
@ide:好点。已编辑。:)
2021-04-30 19:43:39
@Gregir:因为原型上的任何内容都由从该原型继承的所有内容共享。在变量的情况下,您通常不希望那样——例如,您希望每个 Rectangle 都有自己的高度和宽度。所以你在Rectangle构造函数中将它们设置在对象本身上
2021-05-15 19:43:39
我正在努力理解原型,而这样的问题会有所帮助。我有点明白为什么要在原型属性上添加一个方法而不是“this”,但是为什么不对高度和宽度变量做同样的事情并将它们放在原型上?
2021-05-19 19:43:39