教程
https://wangdoc.com/javascript/basic/grammar.html
笔记
1. 语句和表达式的区别
语句主要是为了进行某种操作,一般情况下不需要返回值;表达式是为了得到返回值,一定会有一个返回值。
2. 声明变量未赋值
如果只是声明变量而没有复制,则该变量的值是 "undefined"。undefined 是一个 JavaScript 的关键字,表示 “无定义”。
3. 变量提升、函数提升及 ES6
3.1 变量提升的原理
JS 引擎工作的原理是,先解析代码,获取所有被声明的变量(也就是把文件中所有声明的变量都找出来,然后缓存到内存。这些变量只是声明了但未赋值,变量值自然是 undefined),然后再一行行地运行。这造成的结果就是,所有的变量声明语句,都会被提升到代码的头部,这就是变量提升。
3.2 变量提升的定义
教程:http://www.cnblogs.com/snandy/p/4552078.html
变量提升一个比较严谨的定义:在指定作用域里,从代码顺序上看是变量先使用后声明,但运行时变量的 “可访问性”提升到了当前作用域的顶部,其值为 undefined, 没有“可用性”。
- 可访问性:访问该变量不会抛异常。
- 可使用性:调用该变量进行运行,由于其值为 undefined,达不到原来的效果。
console.log(a);
var a = 1;
按照其他语言的经验,第一句应该报错。但是只是输出了 undefined。但是由于 js 是先解释再执行,实际上相当于执行了下面的代码:
// 无论在文件中哪里被声明的变量都被提升到头部了。
var a;
console.log(a);
a = 1;
3.2 函数表达式也会存在变量提升
function test(){
alert(func);
var func = function(){};
}
test();
这个程序会显示 alert : undefined。注意这个变量提升主要是用 var 声明变量的缘故。因为 var 声明的变量在 JS 解释阶段都会提升到当前作用域的顶部,所以值是 undefined。所以下面的例子会报错:
function test(){
alert(func); // undefined.
func(); // 抛出异常
var func = func(){};
}
3.3 函数声明的名也会提升到当前作用域顶部
function test(){
console.log(f1); // 会输出整个函数的定义。
f1(); // called
function f1(){
console.log("called");
}
}
3.3 函数声明的名 与 3.2 函数表达式 是不一样的。
函数声明的变量名,是用 function 定义了一个函数,3.2 中的函数表达式是 var 修饰的一个变量。
用 function 定义的函数是更牛的,只要定义了,无论是在定义前使用还是在定义后使用都是 OK 的。这个特性也跟 JS 的解释器会先编译后运行有关。比如 Python 中就不能这么搞:
def a():
print(b)
b()
def b():
print("bb")
抛出的 error:
UnboundLocalError: local variable 'b' referenced before assignment
静态语言也不能这么搞,比如 go:
func test(){
a()
func a(){
fmt.Println("gggg")
}
}
我的 ide 直接飘红了。
可见 无论是函数名还是变量的提升,都是拙劣的设计,在写的时候需要避免。
3.4 ES6 中 let / const 的意义
使用 let / const 代替 var 后,变量提升的现象就不存在了。
function test() {
alert(declaredButNotAssigned1); // 报异常
alert(declaredButNotAssigned2); // 报异常
alert(func); // 报异常
let declaredButNotAssigned1;
let declaredButNotAssigned2 = true;
let func = function() {};
}
test();
4 标识符
- 允许使用 和 _, 在 Python 中是不允许使用 的。
5 注释
由于历史上 JavaScript 可以兼容 HTML 的注释,所以 也被视为合法的单行注释。但是需要注意, --> 只有放在行首才会被当成单行注释,否则会当做正常的运算。
// 自减运算符
a--
5 区块
用花括号括起来的语句叫做一个“区块”。
花括号限制不住 var 定义的变量,花括号外面 var 定义的变量依然有效。
{
var a = 1;
}
a // 1
但是 es6 的 let,花括号就能管住它。
{
let a = 2;
}
a // Uncaught ReferenceError: c is not defined
6 条件语句
6.1 switch 结构
- switch 结构与 Java 相同,需要加 break. Go 则不需要加 break。
- Java 中的 Condition 必须是 byte / short / int 或 char / String 。JS 和 Go 则没有此限制。
- Java 中 Case 的值的数据类型必须与 switch 中变量的类型相同。Go 中则要求 case 的数据类型保持一致即可。
switch(condition){
case val:
...
break;
default:
...
}
6.2 三元运算符
// js & java
condition ? a : b
// python
a if condition else b
// go 没有三元运算符
7 条件语句
7.1 do... while 循环
这也是 JS 抄 Java 的地方,无论 while条件是否成立,do 至少执行一次。
do{
语句
} while(条件);
我觉得这个do...while 非常别扭,python 中也有类似较劲的 ---------- for ... else ...
for ... else ... 的用法是,如果 for 正常执行完成,则执行一次 else。
我一直觉得这个没什么卵用,但是在 A 公司,他们却这么干
for i in range(n):
// 重试某个事情,比如重连操作
if success:
break
else:
raise Exeception("重试失败")
7.2 break 和 continue 语句
这两个语句,之前也是知道用法,但是不知道使用场景。
重点在于这两句:
- break 能中断一个循环,所以当一般和 if 配合使用,达到目的就中断。
- continue 之后的代码在此次循环中不执行会被跳过,执行下一次代码。
7.3 标签
label:
语句
标签用的也比较少,使用场景是配合 continue 和 break, 跳出多重循环。
top:
for(let i = 0;i<5;i++){
for(let b=0;b<10;i++){
if (b * i > 30){
break top;
}
}
}
这样就把最外层的 for 循环给打断了,这样不就节省 CPU 了吗?
continue 的作用也是如此。
网友评论