【问题标题】:Javascript "if" Order of OperationsJavascript“如果”操作顺序
【发布时间】:2012-10-22 15:12:15
【问题描述】:

假设你有一个非常基本的 person 对象,它有两个值和一个函数:

function personObject() {
    this.name = 'First Name';
    this.placeInLine = 1;
    this.setPlaceInLine = function(place) {
        this.placeInLine = place;
    }
}

我们设置了一些这样的变量:

var john = new personObject();
var bill = new personObject();
var message = "";

现在看下面三个代码sn-ps...

---代码#1---

if(john.placeInLine < bill.placeInLine) message = "John is before Bill";
else message = "John is not before Bill";

RESULT: message = "John 不在 Bill 之前"; // 因为1不小于1

---代码#2---

bill.setPlaceInLine(2); // change Bill's place to 2 (instead of default of 1)
if(john.placeInLine < bill.placeInLine) message = "John is before Bill";
else message = "John is not before Bill";

RESULT: message = "John 在 Bill 之前"; // 因为 1 小于 2;

---代码#3---

if(john.placeInLine < bill.setPlaceInLine(2)) message = "John is before Bill";
else message = "John is not before Bill";

RESULT: message = "John is not before Bill": // 为什么?

比较后是否调用了 .setPlaceInLine 函数?还是运行该函数的行为会返回一些东西,然后与 john.placeInLine 进行比较?

【问题讨论】:

  • 在 sn-ps 中修复了这个问题 - 很抱歉造成混乱

标签: javascript conditional-statements operator-precedence


【解决方案1】:

因为setPlaceInLine 方法没有显式返回,因此返回undefined。而1 &lt; undefined 的计算结果为falseundefined 被转换为Number,给出NaN,而1 &lt; NaN 肯定是false1 &gt; NaN 也是false,顺便说一句)。

虽然您可以通过让 setter 方法返回分配的值来解决此问题:

PersonObject.prototype.setPlaceInLine = function(place) {
  return this.placeInLine = place;
}

...我认为单独使用 setter 和 getter 会更好(更干净)(就像在您的代码 #2 示例中一样)。

作为旁注,我建议使用原型来设置对象方法(就像我在示例代码中所做的那样)。其原因在this answer 中得到了很好的解释:基本上使用原型,您将只创建一个函数实体,供所有创建的对象使用,而使用this.someMethod,您将在每次调用构造函数时创建一个新函数。

【讨论】:

  • 啊!!!现在我明白了。我在 bill.setPlaceInLine(2) 调用上尝试了 typeof,它确实返回“未定义”,这是比较使用的。现在我明白了。谢谢你的澄清!
  • 快速提问——我的“人”对象只是我编造的一个例子……我实际上是在从另一个库中调用一个对象的函数。在 setter 上没有返回值是通用标准吗?还是这个库构建得不好,它应该有一个返回值?
  • @user1607577 大多数库都会返回你正在操作的对象,这样你就可以像bill.placeInLine().changeName("billl")那样进行链式操作
【解决方案2】:

您正在与函数的返回值进行比较。

除非您实际上通过return this.placeInLine; 返回一个值,否则它将与undefined 进行比较,结果总是false

将您的代码更改为:

this.setPlaceInLine = function(place) {
    return this.placeInLine = place;
}

【讨论】:

    【解决方案3】:

    setPlaceInLine 不返回任何内容。并且没有任何东西被评估为小于 1。 您可以更新 setPlaceInLine 以返回值:

    function personObject() {
        this.name = 'First Name';
        this.placeInLine = 1;
        this.setPlaceInLine = function(place) {
            this.placeInLine = place;
            return place;
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-02-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多