2013-12-14 147 views
0

比较代码1和代码2,哪一个是正确的?为什么在构造函数中使用这个关键字

function Rectangle(height, width) { 
    this.height = height; 
    this.width = width; 
    this.calcArea = function() { // why use this here? 
     return this.height * this.width; 
    }; 

} 

码2 我认为它的罚款与此:

function Rectangle(height, width) { 
     this.height = height; 
     this.width = width; 
     calcArea = function() { 
      return this.height * this.width; 
     }; 

    } 
+2

在第一个片段中,'calcArea'是'new Rectangle()'创建的'Rectangle'的一个属性。在第二个片段中,'calcArea'是一个全局变量。 –

+0

@ChrisMartin我们如何确保它是全球性的? – thefourtheye

+0

阅读https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Values,_variables,_and_literals,特别是“声明变量”部分。 –

回答

1

如果你不使用thiscalcArea将无法​​通过矩形的对象访问。当你说,

this.calcArea = function() ... 

创建在当前对象(this)和功能的新变量将被分配给它,从而使该对象将有机会获得它。

试试看这些陈述,有无this。你会更好地理解。

var a = new Rectangle(1, 2); 
console.log(a.calcArea()); 
+0

使用'this.calcArea = function()...'将创建一个属于类“Rectangle”类的实例 - 所以如果你创建了10,000个“Rectangle”实例,那么你还将创建10,000个“calcArea”实例'功能。我们应该做的是将成员函数附加到类的原型 - 例如:function Rectangle(w,h){this.setWidth(w); this.setHeight(H);}; Rectangle.prototype.setWidth = function(w){this.width = w;}; Rectangle.prototype.setHeight = function(h){this.height = h;}; Rectangle.prototype.calcArea = function(){return this.width * this.height;};' – MT0

+0

@ MT0 OP只是想知道为什么'this'在那里被使用。 – thefourtheye

+0

OP想知道“哪一个是正确的?” – MT0

0

第二个版本将设置全局变量calcArea,以便在构造对象的实例时为对象执行特定的操作。需要使用此设置来设置特定对象的属性。

0

当你序言的方法和属性与“本”在你的构造,他们允许获得与构造函数使用这些属性和方法,并将这些属性和方法新创建的对象创建的新对象。

如果您创建一个基于你不使用“这个”作为序言油杉,并期待在铬调试器您会收到以下错误矩形构造的版本,一个新的对象:

Object #<Rectangle> has no method 'calcArea' 

总之它根本不被认可。

不使用“this”的其他方面是该方法变成'全局'。

这里是一个代码示例演示:

function Rectangle(height, width) { 
    this.height = height; 
    this.width = width; 
    calcArea = function() { // Not prefaced with 'this' 
     return 'hello world'; 
    }; 

} 


var aNewObj = new Rectangle(10,10); 

console.log(calcArea()) // Notice this is not aNewObj.calcArea() ...just calcArea() but its still accessible. 
1

which one is correct?

这取决于你如何看待 “正确”:

  • 要么声明不能被正确解析?
    • 不,这两个都是有效的JavaScript。
  • 哪一个会计算calcArea
    • 代码1会正确计算它,而代码2不会创建Rectangle类的成员函数,但是您可以通过有点难度的广告重定向来正确计算它。见下文。
  • 是创建类的好习惯吗?
    • 不,他们都不是。见底部。

码1 - calcArea()

如果您在随后的代码1创建Rectangle的新实例:

function Rectangle(height, width) { 
    this.height = height; 
    this.width = width; 
    this.calcArea = function() { // why use this here? 
     return this.height * this.width; 
    };  
} 

var rect = new Rectangle(3, 4); 
console.log(rect.calcArea()); 

将正确输出12

代码2 - calcArea()

如果创建Rectangle在随后码2的新实例:

function Rectangle(height, width) { 
    this.height = height; 
    this.width = width; 
    calcArea = function() { 
     return this.height * this.width; 
    }; 
} 

var rect = new Rectangle(3, 4); 
console.log(rect.calcArea()); 

将抛出一个错误:TypeError: rect.calcArea is not a function

calcArea是,而是附着在全球范围内,所以我们可以做:

console.log(calcArea());

将输出NaNcalcArea在全球范围内的一部分,所以没有一个Rectangle类的任何实例的知识和全球范围内不具有heightwidth属性。

如果我们这样做:

var rect = new Rectangle(3, 4); 
width = 7; // Set in the global scope. 
height = 10; // Set in the global scope. 
console.log(calcArea()); 

然后,它会返回70(而不是12以来,内calcArea()this引用全球范围内,而不是rect对象)。

如果我们改变什么this是指使用.call()调用该函数:

var rect = new Rectangle(3, 4); 
width = 7; // Set in the global scope. 
height = 10; // Set in the global scope. 
console.log(calcArea.call(rect)); 

则输出12(因为this现指rect对象,而不是全球范围)。

您可能不希望每次使用calcArea()都需要这样做。

为什么代码1不是最佳

代码1将工作,但并不是最佳的解决方案,因为每次创建新Rectangle对象时,它会创建一个calcArea的属性,对象是一个不同的功能任何其他Rectangle对象的任何calcArea属性。

你可以看到这一点,如果你这样做:

function Rectangle(height, width) { 
    this.height = height; 
    this.width = width; 
    this.calcArea = function() { // why use this here? 
     return this.height * this.width; 
    };  
} 

var r1 = new Rectangle(3, 4), 
    r2 = new Rectangle(6, 7); 

console.log(r1.calcArea.toString() === r2.calcArea.toString()); // Line 1 
console.log(r1.calcArea === r2.calcArea);      // Line 2 

将输出true测试的功能字符串表示的时候是相同的,但false测试功能是否相同的时候。

这是什么意思?如果您创建了1万个Rectangle实例,那么您将拥有10,000个不同的calcArea属性实例,并且每个副本都需要额外的内存(外加时间分配内存并在末尾垃圾收集)。

什么是更好的做法?

function Rectangle(height, width) { 
     this.setHeight(height); 
     this.setWidth(width); 
} 
Rectangle.prototype.setHeight = function(height){ this.height = height; } 
Rectangle.prototype.setWidth = function(width ){ this.width = width; } 
Rectangle.prototype.calcArea = function(){ return this.height * this.width; } 

然后,如果你这样做:

var r1 = new Rectangle(3, 4), 
    r2 = new Rectangle(6, 7); 

console.log(r1.calcArea.toString() === r2.calcArea.toString()); // Line 1 
console.log(r1.calcArea === r2.calcArea);      // Line 2 

它将返回true两个 - 这意味着r1.calcArear2.calcArea指的是相同的功能,不管有多少实例的Rectangle有。

+0

内存管理! thx这么多提示! – user3057928

相关问题