var x = true;
if (x == true) {
console.log(typeof(x));
let x = false;
};
console.log(x);

很抱歉新编程并收到此错误: 错误:未定义x。
我非常困惑。
答案 0 :(得分:4)
它看起来不像,但你声明的两个变量是不同的。您的var
声明就是其中之一,而let
声明则不同。你通过用同一个变量命名它们而感到困惑。
let x
严格存在于if
区块内。此let x
是该块中唯一可以存在的x
,您在尝试x
时声明它之前尝试使用console.log
。
在用var
声明变量之前,你可以使用变量,但是让const不会让你。
此外,我强烈建议您不要在代码中混用var
和let
。如果你这样做,你必须真正理解发生了什么。
var x = true; // first x variable
if (x == true){ // first x variable
console.log(typeof(x)); // second x variable, used before declaration
let x = false; // second x variable created in `if` block
};
console.log(x); // first x variable
编辑: 您的后续问题仍然是两个不同的变量。你唯一做的就是强制代码让它看起来更像是同一个变量。
var x = true; // first x
if (x == true) { // first x
let x = false; // second x
console.log(x); // second x, false
};
console.log(x) // first x, true
答案 1 :(得分:1)
这个解释有点棘手,但我会试试;
var x = true;
if (x == true) {
console.log(typeof(x)); // <-- Error: x is not defined.
let x = false;
};
console.log(x); // true
最后一行实际上很好,因为你在前面定义了x
。
if
声明中发生的事情是,JavaScript向前看并看到您已在该范围内的某处声明x
(let
或const
),但它尚未到达那条线。
因此仅仅在同一范围内的某个地方let
或const
只会导致该变量无法定义。
如果你把它向上移动,一切都很好:
var x = true;
if (x == true) {
let x = false;
console.log(x); // false
};
console.log(x); // true
如果您不重新声明x
,那也没关系:
var x = true;
if (x == true) {
let y = false; // different variable name (won't "shadow" the `x` from above)
console.log(x,y); // true false
};
console.log(x); // true
var
表现不同:
if (true) {
console.log(y); // undefined
var y = false; // `var` is less strict. The declaration of `y` is hoisted to the top of the scope, but it's not assigned until this line
console.log(y); // false
};
答案 2 :(得分:-1)
每个人都缺少的解释部分是声明是hoisted,这意味着宣言被带到了开头。
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.myfirstapp">
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name="com.example.myfirstapp.MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name="com.example.myfirstapp.DisplayMessageActivity"
android:parentActivityName="com.example.myfirstapp.MainActivity">
<!--The meta-data tag is required if you support API level 15 and lower -->
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value="com.example.myfirstapp.MainActivity"/>
</activity>
</application>
</manifest>
尤其如此。对于<?xml version="1.0" encoding="utf-8"?>
<resources>
<!--<color name="colorPrimary">#087609</color>
<color name="colorPrimaryDark">#002900</color>
<color name="colorAccent">#327f4f</color>-->
</resources>
来说,事情有点不同,而且提升一词并不是最准确的。但了解正在发生的事情很有用。
执行时,您的代码将看起来像这样(不完全但是提出了想法)
<resources>
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat">
<!-- Customize your theme here. -->
<!--<item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="colorAccent">@color/colorAccent</item>
-->
</style>
</resources>
现在一切都应该有意义:var
是指let
与var x = true;
if (x == true) {
let x // hoisted at top of scope, for let scope is this if block
console.log(typeof(x));
x = false;
};
console.log(x);
一起声明但尚未初始化。
为了更清楚,这就是typeof(x)
内x
引用下面一行中声明的let
而不是开头的x
的原因:因为声明了该块内部的x存在于此块的开头