【JS全解】JS语法

154 阅读7分钟

JS语法

表达式与语句

  • 表达式:是一组代码的集合,JavaScript解释器会将其计算出一个值。例:3+4
  • 语句:JS整句或命令, JS语句是以分号结束(可以省略)。例:alert()
  • 区别:表达式计算出一个值,但语句用来自行以使某件事发生(做什么事)。
  • 在某些情况,也可以把表达式理解为语句,因为它是在计算结果,也是做事。
  • 值和返回值
    • 1 + 2表达式的为3。
    • add(1, 2)表达式的值为函数的返回值
    • 函数的值被称为返回值,也只有函数有返回值,要注意用词严谨性。
  • console.log()的返回值是undefiend。
    1+1 // 2
    console.log // ƒ log() { [native code] },它本身
    console.log(1) // undefined
    
    • 这里console.log(1)的1只是函数的输出值,并不是返回值。
    • 可以在开发者工具Console中来查看函数的返回值。

大小写敏感

  • JS大小写敏感。
  • var a和var A是不同的。
  • object和Object是不同的。
  • 注意
    • 虽然Chrome输入window会返回Window,但它俩实际上不是同一个东西。一般都用前者。

空格和回车

  • JS中大部分空格没有实际意义。
    • 只要不影响断句,随便加空格。
  • JS中大部分回车没有实际意义。
    • 但return后面不能加回车。如果在return后面不加任何内容,直接回车,JS会在return后自动补一个undefined。
      function fn() {
      	return
      	1
      }
      console.log(typeof(fn())) // undefined
      

标识符

  • 规则
    • 第一个字符,可以是Unicode字母$_或中文。
    • 后面的字符,除了上面所说,还可以有数字。
    • 不能以数字开头
  • 变量名是标识符
    • var _ = 1
    • var $ = 2
    • var _____ = 6(很难数,虽然合法,但不要这么写)
    • var 你好 = 'hi'
  • 拼音标识符不如直接写中文。

注释

  • 写代码不是注释越多越好。
  • 单行注释:// 注释内容
  • 多行注释:/* 注释内容 */
  • 注释的分类
    • 好的注释
      • 踩坑注解。
      • 为什么代码会写得这么奇怪,遇到什么bug。
    • 不好的注释
      • 把代码翻译成中文。
      • 过时的注释。
      • 发泄不满的注释。
  • 不好的注释会把重要的注释给稀释了(信噪比),因此尽量不要乱写注释。

区块block

  • 把代码包裹在一起
    	{
    		let a = 1;
    		let b = 2;
    	}
    
  • 一般与if、for、while合用。

条件语句

if语句

  • 语法
    if (表达式) {
    	语句1
    } else {
    	语句2
    }
    
  • {}在语句只有一句的时候可以省略,但不建议这样做。
    let a = 1
    if (a < 100) 
    	if (a < 10)
    		console.log(a) // 1
    
  • if语句及其表达式被识别为“一条”语句。
  • else后的{}也可以去掉,这也是elseif的由来。
    let a = 1 
    if (a > 100) {
    }else
    		console.log(a) // 1
    
  • 注意
    • a = 1的返回值为1,a = 2的返回值为2,也因此if(a = 数值)这个if表达式永远为true。
    • 建议在JS中用===代替==
    • if (1 = a) {语句1}可以实现用=来表示判断,而不必担心=被识别为赋值符。

if语句最推荐的写法

if (表达式) {
	语句
} else if (表达式) {
	语句
} else {
	语句
}

if语句次推荐的写法

function fn() {
	if (表达式) {
		return 表达式
	}
	if (表达式) {
		return 表达式
	}
	if (表达式) {
		return 表达式
	}
}
  • 因为return之后的语句不会执行,因此不用加else,直接判断就行。

switch语句

  • 语法
    switch (数据) {
    	case1:
    		代码1
    		break
    	case2:
    		代码2
    		break
    	default:
    		代码n
    		break
    }
    
  • 找到跟小括号里数据全等的case值,并执行里面对应的代码。
  • 若没有全等===的则执行default里的代码。
  • 注意
    • switch语句一般用于等值判断,不适合于区间判断。
    • 没有break会造成case穿透(跨case执行)。
    • 但也可以利用break穿透
      switch (a) {
      	case 1:
      	case 2:
      		console.("a<3")
      		break
      	case 3:
      		console.("a>3")
      		break
      }
      
    • 如果数据是从prompt中得到的,则对比值必须要加引号

问号冒号表达式

  • 语法:条件 ? 满足条件执行的代码 : 不满足条件执行的代码
  • 判断条件是否为true,为true则执行第一条代码,若为false,执行第二条代码。
  • 一般用来取值。
  • 能用问号冒号表达式的时候就不要用if else

&&短路逻辑

  • 语法:表达式1 && 表达式2
  • 只有表达式1表达式2都为true,整个式子才为true。
  • &&语句中,输出值为最后运行的表达式的值
  • &&短路:如果左边的代码为false,那么右边的代码就不会执行。
    • 如果表达式1为false,那么会输出表达式1的值,即false。
    • 如果表达式1为true,表达式2为false,那么会输出表达式2的值,即false。
    • 如果表达式1为true,表达式2为true,那么会输出表达式2的值,即true。
  • &&输出值不一定只有布尔值,以上只是方便理解。
  • 可以用&&来进行版本的判断,防止某些方法在某些浏览器中不支持。
    console && console.log && console.log('h1')
    
    • 如果console存在,那么判断console.log存不存在。
    • 如果console.log存在,那么执行console.log('h1')

||短路逻辑

  • 语法:表达式1 || 表达式2
  • 表达式1表达式2中有一个表达式为true,整个式子就是true。
  • ||语句中,输出值为最后运行的表达式的值
  • ||短路:如果左边的代码为true,那么右边的代码就不会执行。
  • 可用||来判断某个值是否存在。
    a = a || 100
    
    • 如果a存在一个值,那么a = a,对a的值没有影响。
    • 如果a不存在,那么100作为保底值,将会被赋予给a。

循环语句

while循环

  • 语法
    while (循环条件) {
    	要重复执行的代码(循环体)
    }
    
  • 判断循环条件的布尔值。
  • 当循环条件为true,而执行语句。
  • 当执行完语句,再次判断循环条件的布尔值。
  • 当循环条件为false,则直接退出while循环。
  • wihle(true) {循环体},死循环。
  • 注意
    • 循环需要具备的三要素
      1. 变量起始值
      2. 终止条件
      3. 变量变化量

for循环

  • 语法:
    	for (语句1; 表达式; 语句2) {
    		循环体
    	}
    
  • 先执行语句1,然后判断表达式。
  • 若表达式为true,则先执行循环体,再执行语句2
    • 除非有break退出循环,不然执行了循环体之后,一定会执行语句2。
  • 若表达式为false,则直接退出循环。
  • for循环和while循环的区别
    • 当如果明确了循环的次数的时候推荐使用for循环。
    • 当不明确循环的次数的时候推荐使用while循环。
  • for循环的4个部分都是可以省略的,但是分号要留下,例:for(let i = 1;;) {console.log(i)}

break和continue

  • continue:退出当前一次循环。
  • break:退出所有循环,并且break会跳过for循环的语句2。
  • 如果有两层循环,break只会跳出当前这一层的循环。

label

  • 语法
    {
    	console.log(1);
    	break foo;
    	console.log('本行不会输出');
    }
    console.log(2);
    
  • {}这是一个label标签,内部只是代码块,并不是对象。
  • 如果要将它变为对象,需要var a = {}
  • 注意
    • chrome浏览器中,将单行的{a: 1}识别为了对象,但这情况不统一。

拓展

“,”和“;”

  • ,表示一句话还没结束
    a = 1
    if (a === 2)
    	console.log(a), console.log('a等于2') // 没有输出值
    
  • ;表示一句话结束了
    a = 1
    if(a === 2) 
    	consoloe.log(a); console.log('a等于2') // a等于2
    

for循环下的setTimeout

  • 易错案例
    for (var i = 0; i < 5; i++) {
    	setTimeout(()=>{
    	console.log(i)
    	}, 0)
    }
    
    • 这个循环的结果为5、5、5、5、5。
    • 这个案例中,由于setTimeout的存在,console.log(i)在for循环执行结束后过一段时间才执行。在循环结束后,i的值已经变成5,也因此会循环打出5个5。
    • 即for循环的执行,是比setTimeout优先度要高的。
  • 但let出现后,专门应对这种情况进行改进,为for-let-setTimeout设计了专门的运行方式。
    for (let i = 0; i < 5; i++) {
    	setTimeout(()=>{
    	console.log(i)
    	}, 0)
    }
    
    • 这个循环的结果为1、2、3、4、5。

方方の敦敦教诲

  • 其一:永远使用最没有歧义的写法。