javascript中使用var关键字的箭头函数与同名混淆的正则函数
Arrow function using var keyword and regular function with same name confusion in javascript
为什么这个记录 1 ?这让我感到困惑,任何人都可以解释一下吗?
(function(){
var hello = () => {
console.log(1);
}
function hello () {
console.log(2);
}
return hello()
})()
函数声明(以 function functionName(
开头的语句)被提升到它们封闭范围的顶部,并首先分配给它们的函数名称标识符,然后在该范围内运行任何其他内容.. [= 赋值14=] 没有。
它是一个箭头函数这一事实并不特别重要 - 在同一点的 function
赋值会产生相同的结果。
(function(){
var hello = function() {
console.log(1);
}
function hello () {
console.log(2);
}
return hello()
})()
您的代码等同于
(function(){
// hello identifier gets created at the very beginning
var hello;
// hoisted function declaration assigns to `hello`:
hello = function hello () {
console.log(2);
}
// assignment with =, not hoisted, assigns to `hello`
hello = () => {
console.log(1);
}
return hello()
})()
我建议至少使用 ES2015+ 语法,这将有助于防止您发生此类事故 - 如果您使用 let
或 const
,它将禁止重新声明变量。
(function(){
let hello = () => {
console.log(1);
}
function hello () {
console.log(2);
}
return hello()
})()
因为:
- 函数声明在与
var
声明 相同的绑定环境中创建标识符(更具体地说,“绑定”)
var
对已存在的绑定的声明不是错误
- 函数声明在进入函数或全局范围(“提升”)时进行处理,因此它们首先分配给绑定
因此您的代码正在创建一个绑定,将 declared 函数分配给它,然后用箭头函数覆盖该值。有效:
(function(){
// Declaration of the var-scoped binding happens first
var hello;
// Then the function declaration is processed, assigning
// the function to the binding
hello = function hello() {
console.log(2);
};
// Then the step-by-step code begins and processes
// the assignment
hello = () => {
console.log(1);
};
return hello();
})();
旁注:var
实际上已弃用,没有理由在现代代码中使用它。相反,请使用 let
或 const
。他们有更理性的行为:
- 它们是块作用域的,而不是函数作用域或全局作用域的(除非它们出现在函数或全局作用域的顶层)
- 重复声明是错误的(包括
let
或 const
声明会与 var
风格的声明(如函数声明)冲突)
- 在全局范围内,它们位于嵌套在全局
var
范围内的内部范围内,并且不在全局对象上创建属性
你的例子会给你一个很好的,有用的错误 let
或 const
:
(function(){
let hello = () => {
console.log(1);
};
function hello () {
console.log(2);
}
return hello();
})()
为什么这个记录 1 ?这让我感到困惑,任何人都可以解释一下吗?
(function(){
var hello = () => {
console.log(1);
}
function hello () {
console.log(2);
}
return hello()
})()
函数声明(以 function functionName(
开头的语句)被提升到它们封闭范围的顶部,并首先分配给它们的函数名称标识符,然后在该范围内运行任何其他内容.. [= 赋值14=] 没有。
它是一个箭头函数这一事实并不特别重要 - 在同一点的 function
赋值会产生相同的结果。
(function(){
var hello = function() {
console.log(1);
}
function hello () {
console.log(2);
}
return hello()
})()
您的代码等同于
(function(){
// hello identifier gets created at the very beginning
var hello;
// hoisted function declaration assigns to `hello`:
hello = function hello () {
console.log(2);
}
// assignment with =, not hoisted, assigns to `hello`
hello = () => {
console.log(1);
}
return hello()
})()
我建议至少使用 ES2015+ 语法,这将有助于防止您发生此类事故 - 如果您使用 let
或 const
,它将禁止重新声明变量。
(function(){
let hello = () => {
console.log(1);
}
function hello () {
console.log(2);
}
return hello()
})()
因为:
- 函数声明在与
var
声明 相同的绑定环境中创建标识符(更具体地说,“绑定”)
var
对已存在的绑定的声明不是错误- 函数声明在进入函数或全局范围(“提升”)时进行处理,因此它们首先分配给绑定
因此您的代码正在创建一个绑定,将 declared 函数分配给它,然后用箭头函数覆盖该值。有效:
(function(){
// Declaration of the var-scoped binding happens first
var hello;
// Then the function declaration is processed, assigning
// the function to the binding
hello = function hello() {
console.log(2);
};
// Then the step-by-step code begins and processes
// the assignment
hello = () => {
console.log(1);
};
return hello();
})();
旁注:var
实际上已弃用,没有理由在现代代码中使用它。相反,请使用 let
或 const
。他们有更理性的行为:
- 它们是块作用域的,而不是函数作用域或全局作用域的(除非它们出现在函数或全局作用域的顶层)
- 重复声明是错误的(包括
let
或const
声明会与var
风格的声明(如函数声明)冲突) - 在全局范围内,它们位于嵌套在全局
var
范围内的内部范围内,并且不在全局对象上创建属性
你的例子会给你一个很好的,有用的错误 let
或 const
:
(function(){
let hello = () => {
console.log(1);
};
function hello () {
console.log(2);
}
return hello();
})()