如何影响JavaScript代码的新关键字

时间:2015-11-01 03:32:53

标签: javascript

<!DOCTYPE html>
<html>
<body>
<p>Counting with a local variable.</p>
<button type="button" onclick="myFunction()">Count!</button>
<p id="demo"></p>
<script>
function Add(x) {
    this.counter = x;
   return function () {return this.counter += 1;}
};
var add = Add(0);

当我用"var add = Add(0);"替换"var add = new Add(0)"时,输出显示为“NaN”。为什么?以及这实际上是如何运作的?

function myFunction(){
document.getElementById("demo").innerHTML = add(); 
  for each click 1, 2, 3 ....

}
</script>
</body>
</html>

3 个答案:

答案 0 :(得分:2)

new用于根据现有定义(存储在Add中)创建新实例。您没有生成实例,而是返回一个函数,因此它无法按预期运行。

此表格应该有效:

function Add(x) {
    this.counter = x;

    this.addOne = function() {
        return this.counter += 1;
    }
}

var add = new Add(0);

function myFunction() {
    document.getElementById("demo").innerHTML = add.addOne();
}

关于您的代码返回NaN的原因的问题,让我们来看看您在做什么:

function Add(x) {
    this.counter = x;
    return function () {return this.counter += 1;}
};
var add = new Add(0);
function myFunction(){
    document.getElementById("demo").innerHTML = add(); 
}

在此声明变量add并使用new Add(0)对其进行初始化。首先,Add函数在其自己的作用域中声明一个名为counter的属性,并通过名为x的参数(在本例中为0)为其分配值。然后,它返回一个函数。然后它退出,不再需要,并且是垃圾收集。分配给counter属性的值将被丢弃,因为它所附加的this已超出范围。

您现在有add作为指向函数的指针。它没有名为counter的属性。当您调用add()函数时,它会尝试将{1}添加到this.counter。由于未定义this.counter,因此它自动具有值undefined

如果您尝试向undefined添加号码,则会获得NaN。由于这是在return语句中发生的,因此会返回NaN

答案 1 :(得分:2)

Add(0)new Add(0)之间的区别在于第一个在window上下文中调用该函数。而第二个在新的{}上下文中调用该函数。但是,匿名函数中的this不会引用新的{}上下文,因为它是在window上下文中调用的,因为add()window.add()相同}}

出于调试目的,请尝试将一些警报或console.log添加到您的函数中:

function Add(x) {
    alert('The context Add was called with is: '+this);
    this.counter = x;
   return function () {
alert('The context the anonymous function was called with is '+this);
return this.counter += 1;}
};

然后你会看到this指向的内容。如果window.counter未定义,则您获得NaN,因为return this.counter += 1;正在向undefined添加1,从而导致NaN

就解决方案而言,一个选项是bind函数到你想要它的上下文:
http://jsfiddle.net/eu9r8pau/4/

另一个选择是通过存储对此的引用来利用闭包:
http://jsfiddle.net/eu9r8pau/5/

您还可以将代码重写为更简单的代码:
http://jsfiddle.net/eu9r8pau/6/

答案 2 :(得分:0)

为Dan Lowe的帖子和解释添加另一个变体,这一次关于OP的例子的标题谈论一个局部变量,我认为这是一个私有变量:

<!DOCTYPE html>
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
</head>
<body>
<p>Counting with a local variable.</p>
<button type="button" onclick="myFunction()">Count!</button>
<p id="demo"></p>
<script>
function Add(x) {
   var counter = x;
   return function () {return counter += 1;}
};
var add = new Add(0);
function myFunction(){
  document.getElementById("demo").innerHTML = add();
}
</script>
</body>
</html>

这是,我认为一个闭包的经典例子。变量counter保留在函数Add的范围内,只有增加它的函数才是公共的。

您可以根据需要使用尽可能多的Add实例,并拥有尽可能多的独立计数器。例如,添加另一个从100开始:

var bdd = new Add(100);
function myFunction(){
  document.getElementById("demo").innerHTML = add() + "<br />" + bdd();
}

此页右侧的“相关”列有一个很好的explanation闭包,请看一下。