【问题标题】:How do you use methods created within a constructor to update another variable within the same constructor?如何使用在构造函数中创建的方法来更新同一个构造函数中的另一个变量?
【发布时间】:2013-09-11 18:11:05
【问题描述】:

在开始之前,我想对收到的所有帮助/意见表示感谢。

我在 Stoyan Stefanov 的面向对象编程练习中遇到了一个大问题。虽然这可能是一个练习的问题,但我认为这个问题可以帮助很多初学者(比如我),尤其是 OOP。练习在第 4 章第 4 题中。

我将复制并粘贴提示:“想象一下 String() 构造函数不存在。创建一个构造函数 MyString(),它的作用尽可能接近 String()。你不能使用任何内置的-in 字符串方法或属性,记住 String() 不存在。”

我知道 for-in 循环不应该与字符串一起使用。但我在这种情况下使用它只是为了练习。这也是作者 Stoyan Stefanov 在提示中提出的建议。

这是我到目前为止的代码。我创建了一个名为 MyString 的构造函数,其中包含几个方法和属性。

function MyString(value)
{
  var valUpdated = this.valueOf(); //problems are occuring here; the value in valUpdated should be a string, not an object 

  this.charAt = function(pos) 
  {
      try
      {
        if(typeof pos !== "number")
        {
          throw new Error("Please input a valid number");
        }
        else
        {
          for (var char in valUpdated)
          {
            return char; //problem is occurring here, when I use the original value parameter and not "valUpdated", the first char returned is 0, as expected, otherwise, its "charAt," referring to a method of the object stored in "valUpdated"
            if(Number(char) === pos) //if using the original parameter value (and not valUpdated), this part of the code works just fine
            {
                return char;
            }
          }
        }
      }
      catch (e)
      {
         return "This error occured " + e;
      }
  };  

  this.findLength = function () 
  {
    var counter = 0;
    for (var char in value)
    {
      counter++;
    } 
    return counter;
  };

  this.length = this.findLength();

  this.valueOf = function()  
  {
    var type = typeof value,
        valueNew = value; //i chose not to update the existing variable value to avoid some concept of oop in javascript that i most likely missed
    if (type === "number" || type === "object" || type === "null"      
        || type === "undefined")
    {
      valueNew = "'" + value + "'"; 
      return valueNew;
    }
    else
    {
      return valueNew;
    }
  };
}

问题都发生在构造函数的第一行,我尝试使用该构造函数的 .charAt() 方法,MyString() 到更新我将在所有其他方法中使用的值(这样我可以首先检查以确保使用的输入值(即变量 value 中的引用字符串)是有效字符串或已经首先转换成一个有效的字符串......这就是我所有的问题都发生的地方)。

使用 .valueOf() 方法在代码底部创建精炼的 value 变量。我正在尝试使用此方法并将其值返回到代码块顶部的“var valUpdated”。例如,当我在 .charAt() 方法中使用 valUpdated 变量时,就会出现问题。出于某种原因,当我使用 valUpdated 变量时,它引用了一个对象,即使它应该引用一个字符串 ,即.valueOf() 的返回值是一个字符串,但由于某种原因 typeof valUpdated 变量是一个对象

这可以在“for...in”循环中验证。 .charAt() 方法 中的第一个“return char”语句(此 return char 语句仅用于错误跟踪)返回“charAt”而不是数字引用到字符串字符。这一定意味着 valUpdated 中的值是一个对象,因为“for...in”循环会遍历 object 的每个 property但是,如果 var valUpdated 是一个字符串,它应该根据方法 .valueOf() 的返回值,“属性”将是 字符串的索引,而对象将是实际的字符串

最有趣的部分是如果我使用常规的参数“值”,该参数与 MyString 构造函数一起使用,char 变量可以正常工作并且 char 的值是一个数字,指的是引用字符串中的字符。

***更新:当我获取整个代码块时:

  var valUpdated = this.valueOf(); 

  this.charAt = function(pos) 
  {
      try
      {
        if(typeof pos !== "number")
        {
          throw new Error("Please input a valid number");
        }
        else
        {
          for (var char in valUpdated)
          {
            return char;
            if(Number(char) === pos) 
            {
                return char;
            }
          }
        }
      }
      catch (e)
      {
         return "This error occured " + e;
      }
  };  

...并将其移至构造函数的底部,char 变量 现在返回一个数字。有人可以解释一下吗?我认为 Javascript 可以在代码中使用下面定义的函数并在定义的地方使用它?

【问题讨论】:

  • 要阅读的内容很多......
  • 哈哈是的。带我永远向右。但我认为它真的可以帮助很多人。
  • 在构造函数中使用 var 来模拟私有实例特定变量,然后不得不将所有函数放在构造函数主体中,因为它们不能使用“私有”,否则总是让我有点难过看到那个。 stackoverflow.com/questions/16063394/…

标签: javascript oop object methods this


【解决方案1】:

你调用的valueOf函数不是你定义的函数,而是Object的函数,见链接Object.valueOf。 在构造函数的定义中,这个关键字指的是你new一个实例时正在创建的对象,所以this.valueOf = function(){...};会在这个实例上创建一个属性,这里是一个函数,但是由于它是一个函数表达式,所以你不会在第一行看到它,var valUpdated = this.valueOf(); 正在调用 Object 的方法,该方法恰好是所有用户定义的对象的超类。

您可能还想阅读一些有关 javascript 原型链如何工作的内容,因为您正在谈论 OOP。

【讨论】:

  • 我同意你所说的。唯一的事情是,在我将所有内容移到定义新方法 .valueOf() 的位置之后,只要你使用它,就可以用你自己的同名方法替换超类 Object 方法。定义它。
  • @user2484802 这是真的,但可能不是一件好事。实际上在javascript中只有原型,它就像java中的超类,但仍然不同。当调用一个函数或属性时,搜索从被调用的对象开始,如果没有找到,则继续到原型。通常函数是在原型上定义的(可以看作是一个对象的一个​​属性,你可以阅读一些文章了解更多细节),它们将被所有实例共享,这样你就不会为每个实例创建相同的方法。跨度>
【解决方案2】:

希望在查看此项目页面后提供帮助。149 Stefanov, S. (2013)“面向对象的 JavaScript,第二版”的练习 4。英国伯明翰:Packt。

问题:不使用“String()”或内置方法,编写一个能够接受新参数并返回字符串的 JavaScript 构造函数。

我相信作者期待这样的解决方案: (隐式强制转换为字符串)

function MyString(str) {
   this.str = str;
    return '' + this.str + '';
}

var s = new MyString('hello');

它通过了练习中的所有测试

> s.length;
"5"
> s.[0];
"h"
> s.toString();
"hello"
> s.valueOf();
"hello"
> s.charAt;
"e"

【讨论】:

    猜你喜欢
    • 2014-08-01
    • 2012-06-22
    • 2014-03-12
    • 1970-01-01
    • 2010-09-22
    • 2016-01-18
    • 1970-01-01
    相关资源
    最近更新 更多