理解JavaScript闭包函数

时间:2013-11-26 02:05:11

标签: javascript

我是Javascript的新手,对封闭函数有疑问。

在下面的代码中,我正在创建一个闭包函数并为同一个函数设置一个新的属性firstname。我想确定我创建的函数的属性 - firstname - 并使用代码 - console.log(obj1.firstname);来显示它。

但由于某种原因,它显示为未定义。请告诉我这是什么问题。

<html>
  <head>
    <script>
      outerfunction = function(firstname,lastname) {
        var innerfunction = function (sex) {
        console.log(firstname);
        console.log(lastname);
        console.log(sex)
        }

        console.log('Initialize');
        innerfunction.prototype.firstname = firstname;
        return innerfunction;
      }

      obj1 = outerfunction('Bob','Mcdonald');
      console.log(obj1.firstname);
      obj2 = obj1('Male');

      obj1 = outerfunction('Lucy','Mary');
      obj1('Female');

    </script>

  </head>
  <body>
    This is the body
  </body>
</html>

2 个答案:

答案 0 :(得分:1)

问题在于您使用原型。如果你做innerfunction.firstname = firstname;那应该解决未定义的问题。

outerfunction = function(firstname,lastname) {
  var innerfunction = function (sex) {
    console.log(firstname);
    console.log(lastname);
    console.log(sex)
  }

  console.log('Initialize');
  innerfunction.firstname = firstname;
  return innerfunction;
}

obj1 = outerfunction('Bob','Mcdonald');
console.log(obj1.firstname);
obj2 = obj1('Male');

obj1 = outerfunction('Lucy','Mary');
obj1('Female');

答案 1 :(得分:0)

只是评论:

>  outerfunction = function

应始终声明变量,尤其是全局变量,以便它们不会与具有相同名称或ID的DOM元素发生冲突(变量优先)。一旦你声明了变量,那么在声明将要执行的函数表达式中没有任何意义(如果没有别的,它可以更少地输入,但是在执行任何代码之前使函数可用,而不是在赋值的时候)。所以:

function outerfunction(firstname,lastname) { 

形式参数列表中的项( firstname lastname )是有效声明的局部变量。所以对于内部功能

  function innerfunction(sex) {
    console.log(firstname);
    console.log(lastname);
    console.log(sex)

此函数具有 firstfunction 名字 lastname 的闭包。

>         innerfunction.prototype.firstname = firstname;

仅当 innerfunction 是构造函数时才有用,并且仅当您希望实例继承 firstname 属性时才有用。函数不是从它们的公共 prototype 继承,而是从它们的私有[[Prototype]]继承,这是它们构造时它们的构造函数的公共原型。

> obj1 = outerfunction('Bob','Mcdonald');

这将返回 innerfunction 的“实例”,其中包含 firstname lastname 的闭包。

> console.log(obj1.firstname);

名字 属性位于 obj1.prototype 上(因为那是分配的位置),所以找不到(检查{{ 1}})。

你的一些困惑可能是关于范围链上的标识符解析(即变量 firstname lastname )与对象及其对象属性解析之间的差异obj1.prototype.firstname链(即继承和 innerfunction.protoype.firstname )。