Javascript 为什么在构造函数中使用此关键字
比较代码1和代码2,哪一个是正确的Javascript 为什么在构造函数中使用此关键字,javascript,this,Javascript,This,比较代码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) {
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;
};
}
如果不使用
此
,则无法通过矩形对象访问Calcara
。当你说
this.calcArea = function () ...
在当前对象(this
)中创建一个新变量,并将函数分配给它,以便对象可以访问它
尝试这些语句,包括和不包括this
。你会更明白的
var a = new Rectangle(1, 2);
console.log(a.calcArea());
第二个版本将设置全局变量calcArea,以便在构建对象实例时执行特定于对象的操作。设置特定对象的属性时需要使用此选项。在构造函数中用“this”作为方法和属性的开头时,它们允许使用该构造函数创建的任何新对象使用这些属性和方法,并使这些属性和方法指向新创建的对象 如果您基于矩形构造函数的版本创建了一个新对象,而该矩形构造函数没有使用“this”作为Calcrea的序言,并查看chrome调试器,则会出现以下错误:
Object #<Rectangle> has no method 'calcArea'
哪一个是正确的
function Rectangle(height, width) {
this.height = height;
this.width = width;
this.calcArea = function() { // why use this here?
return this.height * this.width;
};
}
这取决于您如何看待“正确”:
- 两个声明都不能正确解析吗?
- 不,两者都是有效的JavaScript
- 哪一个将计算Calcrea?
- 代码1将正确地计算它,而代码2不会创建
Rectangle
类的成员函数,但是您可以让它正确地计算,这有点困难。见下文
- 代码1将正确地计算它,而代码2不会创建
- 创建类的一个好做法是什么?
- 没有,他们两个都没有。看下面
calcArea()
如果在代码1中创建一个新的矩形实例
,则:
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()
如果在代码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.calcrea不是函数
calcArea
与全球范围相连,因此我们可以:
console.log(calcArea())
将在全局范围的一部分中输出NaN
作为Calcrea
,因此不知道矩形
类的任何实例,并且全局范围没有高度
或宽度
属性
如果我们这样做:
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()
中,此
引用全局范围,而不是rect
对象)
如果我们更改此引用的调用函数:
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
(因为此
现在指的是rect
对象,而不是全局范围)
您可能不希望每次使用calcArea()
时都必须这样做
为什么代码1不是最佳的
代码1可以工作,但不是最佳解决方案,因为每次创建新的矩形
对象时,它都会创建该对象的calcArea
属性,该属性与任何其他矩形
对象的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
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
这是什么意思?如果您创建了10000个矩形
实例,那么calcArea
属性也将有10000个不同的实例,并且每个副本都需要额外的内存(加上分配该内存并在最后对其进行垃圾收集的时间)
什么是更好的练习?
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; }
如果你这样做了:
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
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.calcrea
和r2.calcrea
引用相同的函数,而不管有多少个Rectangle
实例。在第一个代码段中,calcrea
是new Rectangle()创建的Rectangle
的属性
。在第二个代码段中,calcArea
是一个全局变量。@ChrisMartin如何确保它是全局变量?请阅读,尤其是“声明变量”部分。使用this.calcArea=function()…
将创建一个附加到类矩形
实例的属性-因此,如果创建10000个矩形
实例,则还将创建10000个Calcrea
函数实例。应该做的是将成员函数附加到类的原型上,比如:函数矩形(w,h){this.setWidth(w);this.setHeight(h);};Rectangle.prototype.setWidth=函数(w){this.width=w;};Rectangle.prototype.setHeight=函数(h){this.height=h;};Rectangle.prototype.calcrea=function(){返回this.width*this.height;}
@mt0op只是想知道为什么在那里使用这个。