我正在为改变计算器练习编写一些Javascript。其中一个要求是使用对象构造函数;但是,我在对象的一个方法中访问我的对象中的属性时遇到了很多麻烦。
这是我的目标:
function Coin(intValue){
this.intCents = null; //The property
function setCents(intValue) { //Trying access the intCents property from within this method
/// <summary>Sets the intCents property for this object. If the given value is invalid, then the intCents property is given NaN.</summary>
/// <param name="intCents" type="Number">The new intCents value.</param>
if (isValid(intValue)) {
this.intCents = intValue; //---javascript bugs out here!---
} else {
console.error("Invalid value given to Coin Object.");
this.intCents = NaN;
}
}
setCents(intValue);
function getCents() {
/// <summary>Returns the value of intCents.</summary>
/// <returns type="Number">The intCents value.</returns>
return this.intCents;
}
}
以下是我如何使用我的对象:
var objCoin;
var calculateChange = function () {
if (objCoin != null) {
objCoin.setCents(Number.parseInt("67"));
} else {
objCoin = new Coin(Number.parseInt("67"));
}
}
我拿出了一些不必要的代码,但整体基本功能如下: 用户在文本框中输入数字,然后单击网页上的按钮。该按钮通过onclick事件调用calculateChange方法。
在calculateChange方法中,“67”通常是获取文本框值的一些代码。为了简化代码并提供传递什么类型的值的具体示例,我将其替换为“67”。
发布的内容是,假设用户输入整数...
如果我的objCoin变量没有用Coin实例实例化,那么创建一个新实例并通过Coin的构造函数传入用户的输入。如果我的objCoin被实例化,那么使用setCents方法来保存用户的输入。
这是一个截图,显示正在发生的事情以及javascript错误的位置:
根据我的理解,问题似乎与“this”关键词有关,因为它在if语句中显然未定义。尽管如此,我认为我的代码没有任何问题。
根据我在课程中的理解,this.intCents = null;
是为Coin对象创建属性的正确方法,而this.intCents
将是从对象内部引用属性的正确方法。它在物体的确切位置。
我试着阅读以下问题:
'this' is undefined in JavaScript class methods似乎更多地讨论了new关键字并从已创建的对象访问属性。
How does the "this" keyword work?有很多有趣的例子;但是,我仍然没有看到我的代码中的缺陷。
访问intCents
属性我在哪里出错?
这种情况下this
是什么? (我相信它是对象变量objCoin)
使用的程序:
Visual Studio 2015 Enterprise
Google Chrome及其开发人员工具
答案 0 :(得分:2)
您需要将函数定义为已创建对象的属性,如下所示:
function Coin(intValue){
this.intCents = null; //The property
this.setCents = function(intValue) { //Trying access the intCents property from within this method
/// <summary>Sets the intCents property for this object. If the given value is invalid, then the intCents property is given NaN.</summary>
/// <param name="intCents" type="Number">The new intCents value.</param>
if (isValid(intValue)) {
this.intCents = intValue; //---javascript bugs out here!---
} else {
console.error("Invalid value given to Coin Object.");
this.intCents = NaN;
}
}
this.setCents(intCents);
this.getCents = function() {
/// <summary>Returns the value of intCents.</summary>
/// <returns type="Number">The intCents value.</returns>
return this.intCents;
}
}
更好:将它应用于构造函数的原型:
function Coin(intValue){
this.intCents = null; //The property
this.setCents(intCents);
}
Coin.prototype.setCents = function(intValue) { //Trying access the intCents property from within this method
/// <summary>Sets the intCents property for this object. If the given value is invalid, then the intCents property is given NaN.</summary>
/// <param name="intCents" type="Number">The new intCents value.</param>
if (isValid(intValue)) {
this.intCents = intValue; //---javascript bugs out here!---
} else {
console.error("Invalid value given to Coin Object.");
this.intCents = NaN;
}
}
Coin.prototype.getCents = function() {
/// <summary>Returns the value of intCents.</summary>
/// <returns type="Number">The intCents value.</returns>
return this.intCents;
}
您所做的是:您创建了一个名为的函数(与创建变量类似,但不完全相同)。此定义发生在构造函数中,因此其“可见性”仅限于该函数的边界。此行为实际上用于模拟私有属性或方法(即使在ES6中,内部也是如此)。因此难怪该功能无法从外部访问。
现在谈到“this
关键字如何运作”部分:
this
始终访问绑定对象的属性。您可以使用function.bind
方法将任何对象绑定到函数,在该函数内,this
绑定到该对象。此外,您可以使用function.bind
将功能应用于特定对象,但通常情况下,在使用new
关键字时会为您完成此操作:
var x = new Coin( 3 );
new
创建一个对象并将函数Coin
应用于它。稍后将该新对象分配给名为x
的变量(后面意味着:在构造函数完成执行之后)。
在构造函数中,您可以使用this
访问该新对象。如果要将函数创建为该对象的方法,则需要将其分配给如下属性:
this.methodName = function( param ){ ... };
通过这样做,您可以为属性分配一个闭包(匿名函数),这使它成为一个方法。
这允许您稍后在构造函数创建的任何对象上调用该方法:
x.methodName( paramValue );
每个对象都有一个所谓的原型对象。这通常只是查找方法和属性的“后备”:如果在您的对象上找不到您尝试访问的方法或属性,则会搜索其原型对象以查找该标识符。此对象也有一个原型,因此查找将继续,直到搜索到最顶层的父级。如果仍找不到该属性,则为undefined
。
每个function
都有一个名为prototype
的属性:这不是函数本身的原型对象,而是分配给由此(构造函数)函数创建的每个对象的原型对象(使用new
)。因此,通过将这些函数作为属性分配给构造函数原型,您不需要一次又一次地向每个创建的对象添加相同的方法(这意味着,每个创建的Coin
- 对象都有自己的{{1方法=&gt;内存密集型),但是你只定义了一次方法,将它分配给原型对象,每个getCents
的对象相同 - 用{{1创建的对象(只要您不更改原型对象,出于优化原因,您不应该这样做。)
答案 1 :(得分:1)
这可能与How does the “this” keyword work?
重复一个函数这个通常是通过调用设置的( bind ,箭头函数是例外,但它们在这里并不相关)并且是限定为当前执行上下文(箭头函数除外,它采用其直接外部上下文的 this )。
因此,如果构造函数中的 setCents 函数被调用而未设置其 this :
function setCents(intValue) {
if (isValid(intValue)) {
this.intCents = intValue; //---javascript bugs out here!---
} else {
console.error("Invalid value given to Coin Object.");
this.intCents = NaN;
}
}
setCents(intValue);
然后它的 this 将默认为全局对象(或在严格模式下保持未定义)。它不会成为新的实例。
getCents 和 setCents 方法无法从构造函数外部访问,因此很可能它们应该位于构造函数的原型上,因此每个实例都会继承它们,例如
function Coin(intValue) {
this.intCents = null; //The property
// Initialise cents
this.setCents(intValue);
}
Coin.prototype.setCents = function(intValue) {
// isValid not provided so commented out
// if (isValid(intValue)) {
this.intCents = intValue;
// } else {
// console.error("Invalid value given to Coin Object.");
// this.intCents = NaN;
// }
}
Coin.prototype.getCents = function() {
return this.intCents;
}
var aCoin = new Coin(25);
console.log(aCoin.getCents()) // 25
aCoin.setCents(50);
console.log(aCoin.getCents()) // 50
&#13;