-
Notifications
You must be signed in to change notification settings - Fork 3.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
第 108 题:请写出如下代码的打印结果 #190
Comments
Goodbye Jack |
Goodbye Jack
Hello Tom |
Goodbye Jack |
var name = 'Tom';
(function() {
console.info('name', name);
console.info('typeof name', typeof name);
if (typeof name == 'undefined') {
var name = 'Jack';
console.log('Goodbye ' + name);
} else {
console.log('Hello ' + name);
}
})();
var 声明的变量没有块作用域,变量会提升到最近的 function 作用域的上层,但此时只是声明了变量,并没有赋值,到实际运行了赋值语句之后才有值,在之前值为 |
Goodbye Jack; |
Goodbye Jack |
|
为什么把var name改成let name,结果就变成Hello Tom了呢,求大佬解答 |
var 变量提升,所以 name 是 undefined, 答案是 goodbye jack |
var 存在提升关系, let不会提升。 |
先说答案Goodbye Jack; |
var name = 'Tom'; |
你改的哪个var啊 怎么地 他也输出不了 hello Tom |
我感觉和是不是自动执行函数没什么关系,var 会先声明,导致函数作用域内在var声明之前的name都是undefined. var bb = 2
function a(){
if(0){
console.log(bb)
var bb = 1
}else{
console.log(bb)
}
}
a() 就像这个一样,菜鸟小白个人理解,不知道对不对,话说,怎么高亮然后格式化代码。。。 |
https://help.github.com/en/articles/creating-and-highlighting-code-blocks |
吼猴,谢谢 |
因为let声明的变量仅仅在自己的块级作用域起作用,出了这个块级作用域就不起作用 |
这道题会了能不能上京东? |
想啥呢 |
可以的,www.jd.com |
|
不然呢?你是觉得这题low |
let存在于{}作用域内,不存在作用域提升,此题考的是作用域提升问题,自执行函数只是干扰 |
用执行上下文来解释:自执行函数调用后,首先进入执行上下文的创建阶段,该阶段找到函数内的变量声明name,此时为undefined(所以不管if语句是否成立,这个声明都是生效的);之后进入执行阶段,该阶段开始执行if判断,试图为name赋值,由于name在上一阶段刚好为undefined,所以判断通过,成功赋值为jack,最后输出goodbye jack。这道题里如果if判断不满足,那就只能输出undefined了,不会输出全局变量name,因为作用域查找的时候首先找到的是局部变量name |
你说的对。而且变量提升是在执行之前的,所以即使if条件不会执行,里面定义的变量也会提升 |
Goodbye Jack
那么下面的答案又是多少?
Hello Tom 用 ES6 规定,如果区块中存在 总之,在代码块内,使用
|
Goodbye Jack
改一下,应该就方便看懂了
|
这题考点:JS的预编译(敲重点!敲重点!敲重点!) |
var name = 'Tom'; |
变量提升 |
let 存在区域死锁,不会有变量提升,所以name不会是undefined,所以会执行console.log('Hello ' + name); 然后就会找name,在当前function作用域找不到name,就会去外层找name,一直找到window下面的name,此时name是Tom,所以会打印Hello Tom,这个是作用域链的关系。我描述清楚了吗? |
这题考的是变量提升与作用域的知识点,大家都毫无疑问的知道。让人纠结的只是if花括号内的name要不要提升。对于javaScript语言里的var来说没有块级作用域,只有函数作用域!所以函数内的var name会提升到该函数作用域的顶端,而if花括号内的作用域并不是函数作用域,因此能穿透花括号提升到if之前。而let有自己的语法,只要是花括号都会被当作自己的作用域,在作用域外无法访问且不会变量提升。 最终形式: console.log('Goodbye' + 'Jack'); var name = 'Tom';
(function() {
var name;
if (typeof name == 'undefined') {
name = 'Jack';
console.log('Goodbye ' + name);
} else {
console.log('Hello ' + name);
}
})(); |
Goodbye Jack
|
如果你清楚JS中的作用域和变量提升,那么这题将不是问题。 |
函数执行过程分为两步,创建执行环境和执行代码,创建执行环境的时候声明变量,在执行代码阶段给变量赋值。
如果在函数内部的if语句中使用let 声明name,则在创建执行环境的时候不会声明内部变量name(if花括号中name被认为是if的局部变量),在执行代码阶段,找到了全局变量name(全局变量name已经赋值了),所以此时if判断走false分支。
如果在函数内部if语句之前使用let声明name,那么同情况一一样,也会在函数内部声明私有name。所以走true分支
|
Goodbye Jack |
typeof 优先级等级高于 ==, name 进行了变量声明提升,name变成了undefined,typeof name相当于typeof undefined,typeof undefined相当于undefined。因此typeof name == 'undefined'为true。所以输出Goodbye Jack。 |
let声明变量会建立块级作用域,不会产生变量提升 |
Goodbye Jack,变量声明提升 |
var 变量声明提升 |
我有个问题,undefined == 'undefined' 是false啊 |
虽然 == 会隐式的转换 js的数据类型,但一个是字符串,一个是undefined 既变量的默认空值(它只和 null 在两个等于情况下相等),所以是false, 这边你只需要 记住 undefined和null 之间是会相互之间转换的。其他的情况下,它都不会进行 转换的 |
在执行 某段js语句时, 首先 编译器会生成 js 引擎运行时所需要的代码,所以在这段 IIFE中 编译器首先会在当前作用域中 查找是否有声明过 变量name,发现当前作用域内没有,帮你声明变量name,之后再执行赋值操作,其中的最主要的是 用var关键字 声明 会导致变量提升。如果使用 let 就不会这样了。 |
因为,对 let来说,if 也算是块儿作用域,不会发生变量提升。此时,name 就是 外面的 name ,string类型,执行 else 分支。 |
var tt; |
var name = 'Tom';
console.log(name) // 'Tom'
(function() {
var name;
if (typeof name == 'undefined') {
name = 'Jack';
console.log('Goodbye ' + name); // 'Goodbye Jack'
} else {
console.log('Hello ' + name);
}
})();
console.log(name) // 'Tom' |
答案都知道,但是关于换成let的问题 解释一下 |
输出Goodbye Jack var name = 'Tom';
(function() {
if (typeof name == 'undefined') {
var name = 'Jack';
console.log('Goodbye ' + name);
} else {
console.log('Hello ' + name);
}
})(); 等价于 var name = 'Tom';
(function() {
var name;
if (typeof name == 'undefined') {
name = 'Jack';
console.log('Goodbye ' + name);
} else {
console.log('Hello ' + name);
}
})(); |
请写出如下代码的打印结果
|
Goodbye Jack |
var name = 'Tom';
(function() {
if (typeof name == 'undefined') {
var name = 'Jack';
console.log('Goodbye ' + name);
} else {
console.log('Hello ' + name);
}
console.log(name) // Jack, var穿透块级作用域,
})();
//
(function(){
console.log(a);
i=1;
while(i--){
var a = 1
};
console.log(a)
})()
console.log(i)
//
(function(){
console.log(a);
for(let i = 0; i < 1;i++){
var a = 1
};
console.log(a)
})()
console.log(i) |
|
The text was updated successfully, but these errors were encountered: