【问题标题】:Object property "Previous Value" in JavascriptJavascript 中的对象属性“上一个值”
【发布时间】:2010-10-12 07:09:21
【问题描述】:

我刚刚开始思考整个面向对象的事情,所以请耐心等待。

所以,我看到了一个对象函数(用于 Javascript)的示例,您可以在其中分配一个新值,然后将该值分配为该属性的实际值。示例:

function Meat (name, color, price) {
    function newPrice (new_price) {
        this.price = new_price;
    }
 this.name = name;
 this.color = color;
 this.price = price;
 this.newprice = newPrice;
 }

很好,花花公子。现在我可以使用 Bacon.price 或 Bacon.newprice 来指定价格。就个人而言,这似乎是最高级别的语义,因为在功能上它做同样的事情。但作为语义编码的倡导者,我会放任不管。这就是我想要的:

当我更改 Bacon.price 的值时,该对象应包含一个函数,用于将旧值自动存储在名为 oldprice 的属性中。我玩过这个,但无处可去。到目前为止,这是我尝试过的:

function Meat (name, color, price) {
    function oldPrice () {
        this.oldprice = this.price;
    }
 this.name = name;
 this.color = color;
 this.oldprice = oldPrice;
 this.price = price;
 }

///////////////////////

function Meat (name, color, price) {
    this.name = name;
    this.color = color;
    this.oldprice = this.price;
    this.price = price;
}

或多或少的变化。我认为在分配新值之前引用已经分配的值(第一次不会是什么)就足够了。我知道值(或缺少值)在被分配之前存储在某个地方,我只是不知道如何引用它以在它被清除之前将其分配给 oldvalue 属性。


好的,那么问题可能出在我的眼睛或手指上。因为我认为我在询问之前已经尝试过这些建议(我知道,我没有提到它们!)除非我真的很困惑,否则这应该可行:

function Meat(price)
{

    function setPrice(price)
    {
        this.oldprice = this.price;
        this.price = price;
    }

this.price=setPrice;
}

bacon = new Meat()
bacon.price = "Expensive";
document.write(bacon.price+"<br />");
document.write(bacon.oldprice+"<br />");
bacon.price = "Cheap";
document.write(bacon.price+"<br />");
document.write(bacon.oldprice+"<br />");

但我得到的输出是: 昂贵的 不明确的 便宜的 未定义

一切都好,直到最后一个。再一次,我愿意接受视力不好和拼写不好的根源。但我想不通。

【问题讨论】:

    标签: javascript variables object oop


    【解决方案1】:

    这将在您调用 obj.newPrice(xxx); 时存储它 - 我认为您在使用 obj.price = xxx; 时无法自动执行此操作

    function Meat (name, color, price) {
        function newPrice (new_price) {
            this.oldprice = this.price
            this.price = new_price;
        }
     this.name = name;
     this.color = color;
     this.price = price;
     this.newprice = newPrice;
     }
    

    编辑:

    正如@Mauris 所述,Javascript 1.5 确实支持getters and setters(另请参阅here - 您可以将它们视为伪装成属性的方法。

    使用这些,您的代码将如下所示:

    function Meat (name, color, price) {
        function newPrice (new_price) {
            this.oldprice = this.price
            this.price = new_price;
        }
     this.name = name;
     this.color = color;
    
     this.__defineSetter__("price", function(newprice)
     {
           this.oldprice = this.price
           this.price = price;
     });
     }
    

    很遗憾,Internet Explorer 还不支持这种语法。

    【讨论】:

    • 您可以使用 defineSetter。更多信息在这里:ejohn.org/blog/javascript-getters-and-setters
    • @Marius 当然,但前提是您使用的是 jQuery。如果是直接的 JS OOP 代码,那你就做不到。
    • 普通 JS 很烂。然而,defineSetter 不是 jQuery 的东西。但是 IE 不支持它...:/
    【解决方案2】:

    是吗?

    函数 setPrice(price) {
      this.oldprice = this.price;
      this.price = 价格;
    }
    

    【讨论】:

      【解决方案3】:
      store = (function (prev) {
          callee = arguments.callee;
          return function (curr) {
      
              console.log("prev:" + prev, "curr:" + curr);
              store = callee(curr);
          }
      }(0)) //Initial value
      
      store(1); //Output : prev:0 curr:1 
      store(2); //Output : prev:1 curr:2
      store(3); //Output : prev:2 curr:3
      store(4); //Output : prev:3 curr:4
      

      【讨论】:

        【解决方案4】:

        考虑一下您要做什么:
        1.记住旧价格
        2. 将当前价格更改为新价格

        由于这是您要执行的两个步骤,因此您需要将它们粘贴在一个功能中。您需要首先记住当前价格是多少(在 this.oldprice 中),然后然后更改当前价格(this.price)。来自 RoBorg 和 cherouvim 的响应中包含执行此操作的代码。

        【讨论】:

          【解决方案5】:

          嗯,首先我不太确定你是否正确地执行了 OOP Javascript。 OOP Javascript 从一开始就不是真正的面向对象编程,而是使用原型来工作:

          例如:

          function Meat (name, color, price) {
                 if(arguments.length > 0) 
              {
                  this.init(name, color, price);
              }
          }
          
          Meat.prototype.init = function(name, color, price) {
              this.name = name;
              this.color = color;
              this.price = price;
          
              // Initially these are all set to null, 
              // because they don't have an old value yet.
              this.old_name = null;
              this.old_color = null;
              this.old_price = null;
          };
          

          这将构成你的构造函数。

          接下来我们需要添加一些方法来存储你的旧值:

          Meat.prototype.setName = function(new_name) {
              // Store the old name of the meat
              this.old_name = this.name;
              this.name = new_name;
          };
          

          你会为你的肉中的每个属性写一个这样的方法。

          【讨论】:

          • 至少在带有基级类的纯 Javascript OOP 中,它是这样工作的。
          【解决方案6】:

          由于您刚刚开始使用 OO javascript,请听听以下建议:

          不要使用 new 关键字来创建对象。改用函数继承。这样您就可以轻松获取私有变量,而且我认为语法要容易得多。看看吧:

          var meat = function(name, color, price){
             var that = {};
             var name = name;
             var price = price;
             var color = color;
             var oldPrice = null;
             var setPrice = function(p){
                oldPrice = price;
                price = p;
             };
             var getPrice = function(){ return price;};
             var getOldPrice = function(){return oldPrice;};
             that.getPrice = getPrice;
             that.setPrice = setPrice;
             that.getOldPrice = getOldPrice;
             return that;
          };
          

          你可以像这样使用上面的:

          var m = meat("chicken", "white", 100);
          m.setPrice(50);
          var old = m.getOldPrice();
          

          现在你可能需要 getName 和 setName 方法等。如果你想要继承,你可以这样做:

          var cow = function(name){
              var that = meat(name, "spotted", 100);
              that.moo = function() { return name +" moooo"; };
              return that;
          }
          

          无论如何,我可能回答错了问题,但也许你会读到这里并看到光明:)

          【讨论】:

          • 函数继承的重点不是模拟私有变量,而是避免失去this的作用域。
          • 感谢上帝你还在回答我的问题。哦,等等……但实际上,好点。我也应该提到这一点=)。
          【解决方案7】:

          JS 中没有 getter/setter 或运算符重载(目前),因此您确实需要编写一个函数来设置价格并获得那些有趣的副作用。

          【讨论】:

            【解决方案8】:

            您正在覆盖您的价格变量。不要忘记,在 javascript 中,您可以将任何内容分配给变量,因为它不是强类型的。所以,你设置它的方式:

            function Meat(price)
            {
            
                function setPrice(price)
                {
                    this.oldprice = this.price;
                    this.price = price;
                }
            
            this.price=setPrice; //<-- this assigns the function "setPrice" to the variable "this.price"
            }
            
            bacon = new Meat()
            bacon.price = "Expensive"; //<-- this overwrites the "price" variable with a string
            document.write(bacon.price+"<br />");
            document.write(bacon.oldprice+"<br />");
            bacon.price = "Cheap";
            document.write(bacon.price+"<br />");
            document.write(bacon.oldprice+"<br />");
            

            假设您不需要 IE 支持,您可以(如前所述)使用 getter 和 setter。否则,使用您定义的方法:

            bacon = new Meat();
            bacon.setPrice("Expensive");
            document.write(bacon.price+"<br />");
            document.write(bacon.oldprice+"<br />");
            bacon.setPrice("Cheap");
            document.write(bacon.price+"<br />");
            document.write(bacon.oldprice+"<br />");
            

            既然你真的想强制访问这些值,我也会为它们编写 getter:

            bacon.getPrice();
            bacon.getOldPrice();
            

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 2022-08-18
              • 1970-01-01
              • 2018-03-11
              • 2021-10-18
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多