JavaScript词法作用域和动态作用域
JavaScript采用的是词法作用域(lexical scoping),也就是静态作用域。
- 静态作用域:函数的作用域在函数定义的时候就决定了。
- 动态作用域:函数的作用域在函数调用的时候才决定的。
var value = 1;
function f2() {
console.log(value);
}
function f1() {
var value = 2;
f2();
}
f1();
//1
在f1里又调用了f2函数,输出打印value值,首先在f2内部作用域查找是否有value这个局部变量,如果没有,就会沿着作用域链向上寻找,这是我们发现value变量存在,值为1;
假设这里是动态作用域,那当我们执行f2函数的时候发现它的作用域中没有变量,向上层去查找,发现在f1的局部作用域中有value这个变量,值为2,就会输出2;
引用《JavaScript权威指南》的回答就是:JavaScript 函数的执行用到了作用域链,这个作用域链是在函数定义的时候创建的。函数的作用域在函数定义的时候就决定了。
关于作用域的其他例子请看我的另一篇 ES6 (一) 彻底搞懂 var let const
重新梳理一下JS的基本语法:
表达式 语句
表达式是有值的
- 1+2 的值为3
- add(1,2)的值为函数的返回值
- console.log(3)的值为undefined
语句: 用来声明 赋值
var a = 1
标识符规则
- 第一个字符,可以是Unicode字母或$或_或中文(不可以有数字)
- 后面的字符,除了上面所说,还可以有数字,变量名是标识符
例如:
var =1
var $=2
var _=6
var 你好='hi'
if else语句
最推荐的语法格式:{ }在只有一个语句时可以省略,注意是一个语句而不是一行!
if(表达式){
语句1
} else if(表达式){
语句2
} else {
语句3
}
次推荐使用的:
function f(){
if(表达式){
return 表达式
}
if(表达式){
return 表达式
}
}
while 语句
while语句的语法格式:
let a = 0.1;
while (a !== 1) {
console.log(a)
a = a + 0.1 //注意:由于浮点数的计算时不精确的,所以代码会死循环
}
for 语句
for (var i = 0; i < 5; i++) {
console.log(i)
}
console.log(i) //打印出的i是5, 因为当i == 4, i = i + 1 = 5, 然后退出循环
for (let i = 0; i < 5; i++) {
console.log(i)
}
console.log(i) //i是undefined. 因为Let声明的变量不会变量提升
等到for循环执行完毕了,再打印5次i,所以就会打印5个5:
for (var i = 0; i < 5; i++) {
setTimeout(()=>{
console.log(i) //打印出5次5
}, 0)
}
当把var 换成 let, 就会打印出 0, 1, 2, 3, 4:
for (let i = 0; i < 5; i++) {
setTimeout(()=>{
console.log(i)
}, 0)
}
break与continue
- break是跳出离它最近的一个for循环
- continue是跳出本次循环,下次继续
for (var i = 0; i < 10; i++) {
for (var j = 0; j < 5; j++) {
if (i===5) {
break;
}
}
console.log(i) //会打印出0,1,2,3,4,5,6,7,8,9
}
label
foo: {
console.log(1)
break foo; //退出当前的Label,
console.log('本行不会输出')
}
console.log(2)
下面代码块里有一个label, a:1 表示这个标签是a, a的值是1
{
a:1; //a不是一个对象
}