为什么此函数日志未定义(JavaScript闭包)

时间:2015-08-04 15:29:32

标签: javascript closures

想知道为什么init函数最终记录未定义,因为startDate是在调用logStartDate之前定义的。
代码:

var startDate;

var init = function(startDate) {
    this.startDate = startDate;
    logStartDate();
};

var logStartDate = function() {
    console.log(startDate);
};

init('2015-01-02');

4 个答案:

答案 0 :(得分:2)

您的代码可能无效,因为this的值不是您所期望的,因此this.startDate不会更改代码中的变量startDate因此该变量从未初始化。

您在该引用中滥用this,因此这是开始修复代码的地方。实际上,如果您以strict模式运行代码,则代码会生成错误,因为this将为undefinedstrict模式是明确设计用于防止不良编码做法,例如意外错误地使用this

  

为什么this.startDate结构不好,什么是更好的结构?

this用于引用方法调用中的对象,如obj.method()中所示。 method内部this引用objthis可以在其他几种情况下使用,当函数的调用者显式导致{{1}的值时设置为有意义的值。在正常的函数调用中,this将是全局对象,或者在严格模式下将是this,并且通常不应该使用。请参阅this answer,了解undefined的值确切设置为唯一的情况。

在正常的函数调用中,调用者没有为您明确设置this,您根本不应该使用this。实际上,如果您以严格模式运行代码(强烈建议这样做),this功能中this的值将为undefined

如果您只是尝试将名为init的更高级别范围的变量设置为传递给startDate的值,那么您应该将参数名称更改为{{1函数为非冲突名称,然后直接引用init变量,如下所示:

init
  

不是函数表达式是闭包吗?

仅在某些情况下,当某个函数内部的某个内部引用持续时,才会创建一个闭包,它在完成执行后保持函数的作用域。所有函数表达式都不是闭包。您在此代码中没有闭包。有关闭包的更多讨论,请参阅How do JavaScript closures work?

答案 1 :(得分:0)

因为您在init内设置了this.Startdate的值(私有成员变量init)。

您需要修改以使用window范围:

var startDate;

var init = function(date) {
    startDate = date;
    logStartDate();
};

var logStartDate = function() {
    console.log(startDate);
};

init('2015-01-02');

答案 2 :(得分:0)

因为 startDate 2等于 startDate 1,而不是其他 startDate

var startDate;   // 1

var init = function(startDate) {  // startDate here is '2015-01-02'
  this.startDate = startDate;     // not equal to startDate line 1
  logStartDate();
};

var logStartDate = function() {
  console.log(startDate);         // 2, equal to startDate line 1
};

init('2015-01-02');

改为使用这个:

var startDate;

var init = function(date) {
  startDate = date;
  logStartDate();
};

var logStartDate = function() {
  console.log(startDate);
};

init('2015-01-02');

答案 3 :(得分:0)

你遇到的问题是logStartDate试图在console.log中定义你定义的第一个startDate变量,但没有赋值,因此它返回为'undefined'。变量名称的选择不当也部分地造成了这种混乱。

var startDate;                //you defined a new variable startDate
var init = function(date) {   //you defined init, and passed a parameter called date (renamed for clarity)
    this.startDate = date;    //you set this.startDate to the date parameter
    logStartDate();           //you call logStartDate() but have not passed this.startDate as an argument, 
};
var logStartDate = function() {
    console.log(startDate);     // you are console logging the original startDate variable defined at the top of the code block, which did not get assigned a value
};
init('2015-01-02');

更好的实现将是这样的

var init = function(date) {
    logStartDate(date);
};

var logStartDate = function(date) {
    console.log(date);
};

init('2015-01-02');