为什么未定义此函数日志记录(JavaScript关闭)

Why is this function logging undefined (JavaScript closure)

本文关键字:JavaScript 关闭 记录 日志 未定义 函数 为什么      更新时间:2023-09-26

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

var startDate;
var init = function(startDate) {
    this.startDate = startDate;
    logStartDate();
};
var logStartDate = function() {
    console.log(startDate);
};
init('2015-01-02');

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

您在该引用中滥用了this,因此这是修复代码的起点。事实上,如果您在strict模式下运行代码,您的代码将生成一个错误,因为this将是undefinedstrict模式被明确地设计为防止糟糕的编码实践,例如意外地以错误的方式使用this

为什么this.startDate是一个糟糕的结构,什么是更好的结构?

CCD_ 11用于引用方法调用内部的对象,如CCD_。在method内部,this将指代obj,或者当函数的调用方显式地将this的值设置为有意义的值时,this可以在其他一些情况下使用。在正常的函数调用中,this将是全局对象,或者在严格模式下将是undefined,通常不应使用。有关this的值设置为唯一值的具体情况,请参见此答案。

在调用方没有显式为您设置this的正常函数调用中,您根本不应该使用this。事实上,如果您在严格模式下运行代码(强烈建议这样做(,那么this的值将是init函数中的undefined

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

var startDate;
var init = function(initialDate) {
    startDate = initialDate;
    logStartDate();
};
var logStartDate = function() {
    console.log(startDate);
};
init('2015-01-02');

函数表达式不是闭包吗?

只有在某些情况下,当函数内部的某种内部引用持续存在时,才会创建闭包,从而在函数完成执行后保持函数的作用域有效。并非所有函数表达式都是闭包。此代码中没有闭包。请参阅JavaScript闭包是如何工作的?更多关于闭包的讨论。

因为在init内部,您正在设置this.Startdate的值(init的私有成员var(。

您需要修改以使用window作用域:

var startDate;
var init = function(date) {
    startDate = date;
    logStartDate();
};
var logStartDate = function() {
    console.log(startDate);
};
init('2015-01-02');

因为startDate2等于startDate1,而不是其他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');

这里的问题是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');