匿名函数和未定义成员值的问题

时间:2010-11-23 15:36:42

标签: javascript

我在这里问了一个问题: Extending javascript literal object

因为我忘了回来而被解决了。现在我没有忘记返回,我再次未定义,为什么?

<script>
    var secretAgent = (function(){
      var person = {},
          firstName = "James",
          lastName = "Bond";
      person.WhoAreYou = function() {
        alert("My name is " + this.lastName + ", " + this.firstName + " " + this.lastName);
      };
      return person;
    })();
  </script>

  <script>
    secretAgent.WhoAreYou();
  </script>

更新:为什么我的工作不起作用,而我认为我的工作与下面的工作方式相同:

http://enterprisejquery.com/2010/10/how-good-c-habits-can-encourage-bad-javascript-habits-part-1/

//Revealing Module Pattern (Public & Private)
var skillet = (function() {
    var pub = {},
        //Private property
        amountOfGrease = "1 Cup";

    //Public property   
    pub.ingredient = "Bacon Strips";

    //Public method
    pub.fry = function() {
        console.log( "Frying " + pub.ingredient );
    };

    //Private method
    function privateWay() {
        //Do something...
    }

    //Return just the public parts
    return pub;
}());

//Public Properties
console.log( skillet.ingredient ); //Bacon Strips

//Public Methods
skillet.fry();

//Adding a public property to a Module
skillet.quantity = 12;
console.log( skillet.quantity ); //12

//Adding a public method to a Module
skillet.toString = function() {
    console.log( skillet.quantity + " " +
                 skillet.ingredient + " & " +
                 amountOfGrease + " of Grease" );
};

try {
    //Would have been successful,
    //but can't access private variable
    skillet.toString();
} catch( e ) {
    console.log( e.message ); //amountOfGrease is not defined
}

6 个答案:

答案 0 :(得分:3)

您需要在文字本身声明这些属性(而不是分离不相关的变量),如下所示:

var secretAgent = (function(){
  var person = { firstName: "James", lastName: "Bond" };
  person.WhoAreYou = function() {
    alert("My name is " + this.lastName + ", " + this.firstName + " " + this.lastName);
  };
  return person;
})();

You can test it out here

答案 1 :(得分:1)

我看到这里有两个问题。

  1. 再次忘记了回归。 :-) WhoAreYou函数实际上没有返回任何内容,只是提醒。因此secretAgent.WhoAreYou()也返回undefined。
  2. 警报显示“我的名字未定义,未定义未定义”。这是因为所使用的变量的范围。您将WhoAreYou分配到person,并在正文中引用this.lastName。这里的this是指person变量,正如您所看到的,此对象没有lastName属性。
  3. 有两种方法可以解决后一个问题。首先,通过将名称变量添加到person对象:

    var secretAgent = (function(){
      var person = {};
      person.firstName = "James";
      person.lastName = "Bond";
      person.WhoAreYou = function() {
        alert("My name is " + this.lastName + ", " + this.firstName + " " + this.lastName);
      };
      return person;
    }    
    )();
    
    // Although the first three lines would be more natural as:
    var person = { firstname: "James", lastName: "Bond" };
    

    其次,您可以选择删除this引用,它将引用您刚刚定义的局部变量:

    var secretAgent = (function(){
      var person = {},
      firstName = "James",
      lastName = "Bond";
      person.WhoAreYou = function() {
        alert("My name is " + lastName + ", " + firstName + " " + lastName);
      };
      return person;
    }    
    )();
    

    在两个示例中,您当然需要向returns函数添加适当的WhoAreYou

答案 2 :(得分:1)

从变量中删除“this”,因为你在匿名函数中将它们设置为var,使用这个指向该函数,而不是你现在调用它们的“Person”。

<script>
  var secretAgent = (function(){
    var person = {},
    firstName = "James",
    lastName = "Bond";
    person.WhoAreYou = function() {
      alert("My name is " + lastName + ", " + firstName + " " + lastName);
    };
    return person;
  }    
  )();
</script>

<script>
  secretAgent.WhoAreYou();
</script>

示例:JSFiddle

答案 3 :(得分:1)

为什么不呢:

var secretAgent = {
    firstName: "James",
    lastName: "Bond",
    whoAreYou: function() {
        alert("My name is " + this.lastName + ", " + 
              this.firstName + " " + this.lastName);
    }
};

答案 4 :(得分:1)

您定义firstName和lastName的方式不是对象person本身的字段。但是它们是WhoAreYou功能的上限值。所以你可以写这样的函数:

person.WhoAreYou = function() {
    alert("My name is " + this.lastName + ", " + this.firstName + " " + this.lastName);
};

就像那些是函数的私有变量一样。另一种方法是将filelds声明为对象本身,如下所示:

var person = {
    firstName: "James",
    lastName: "Bond",
};

这个方法可以像你写的一样工作。

答案 5 :(得分:1)

变量this在您的情况下为person,同时firstNamelastName被定义为局部变量,但不是person的属性,所以你可以通过名字在匿名函数中访问它们:

var secretAgent = (function(){
  var person = {},
      firstName = "James",
      lastName = "Bond";
  person.WhoAreYou = function() {
    alert("My name is " + lastName + ", " + firstName + " " +lastName);
  };
  return person;
})();
secretAgent.WhoAreYou();