JS 知识总结

150 阅读2分钟

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不是一个对象
}