JS语法

Rinsann 2021年08月13日 370次浏览

JavaScript语法

JS版本

历史版本

  • ES3,IE6支持
  • ES 5,过时了
  • ES6,大部分浏览器支持,总体 一部分垃圾,一部分好
  • ES2019与 ES6差别不大

为什么ES6 一部分是垃圾

  • ES 不能删除以前的特效,要兼容旧网站
  • 也就是以前能运行的网站,以后都要能运行
  • 对比Python 3 就能知道兼容的好处:稳定

在学习JS的时候,取其精华,去其糟粕。

JS之父对JS的评价:它的优秀之处并非原创,它的原创之处并不优秀。

表达式与语句

表达式

  • 1 + 2 表达式的值为3
  • add(1,2) 表达式的值为函数的返回值
  • console.log表达式的值为函数本身
  • console.log(3) 表达式的值是undefined

语句

  • var a = 1 就是一个语句

二者的区别

  • 表达式一般都有值,语句可能有也可能没有
  • 语句一般会改变环境(声明、赋值)
  • 但不是绝对的

大小写敏感

不要写错

  • var a 和 var A 是不同的
  • object 和 Object是不同的
  • function 和 Function 是不同的

空格

大部分空格没有实际意义

  • var a = 1 和 var a=1 没有区别
  • 加回车大部分时候也不影响
  • 只有一个地方不能加回车,那就是return后面

标识符

规则

  • 第一个字符,可以是Unicode 字母或$或者_或中文
  • 后面的字符,除了上面所说,还可以有数字

变量名是标识符

  • var _ = 1
  • var $ = 2
  • var ____ = 6
  • var 你好 = 'hi'

还有一些其他的标识符。

错误的命名

var 9$
Uncaught SyntaxError: Invalid or unexpected token

注释

写代码的时候要加注释

单行注释://

多行注释:/**/

注释的分类

不好的注释

  • 把代码翻译成中文
  • 过时的注释
  • 发泄不满的注释

好的注释

  • 踩坑的注释
  • 为什么代码会写的这么奇怪,遇到什么bug

区块block

把代码包在一起

{
	let a = 1
	let b = 2
}

常常与if 、for 、while 一起使用

if语句

语法

  • if(表达式) {语句1} else {语句2}
  • {} 在语句只有一句的时候可以省略,但不建议这么做

变态情况

  • 表达式里可以非常变态,如 a = 1
  • 语句1 语句2 也有很复杂的情况,如嵌套的 if else
  • 缩进也可以很变态,面试题常常下套
a = 1
if(a === 2)
	console.log('a')
	console.log('a等于2')

使用最没有歧义的写法

if(表达式){

}else if (表达式){

}else

次推荐的写法
function fn(){
	if(表达式){
		return 表达式
	}
	if(表达式){
		return 表达式
	}
	if(表达式){
		return 表达式
	}
}

Switch语句(if..else..升级版)

语法

switch(fruit){
	case "banana":
		//...
		break;
	case "apple":
		//...
		break;
	default:
		//...
}

break

  • 大部分时候不能省略break
  • 少部分时候可以利用break特性

问号冒号表达式(三元表达式)

表达式1?表达式2:表达式3

&&短路逻辑

A && B && C && D 取第一个假值或D,并不会取true/false。window.f1 && console.log('f1存在')

|| 短路逻辑

A || B || C || D 取第一个真值,或者D,并不会取true/false,而是ABCD中的一个

总结

条件语句

  1. if ... else...
  2. switch
  3. A ? B : C
  4. A && B
  5. fn && fn()
  6. A || B
  7. A = A || B

while 循环

语法

  • while (表达式) {语句}
  • 判断表达式的真假
  • 当表达式为真,执行语句
  • 当表达式为假,执行后面的语句
  • 执行完再次判断表达式的真假

其他

  • do...while 循环语句至少执行依次,用的很少。

for循环

语法糖

  • for是while循环的方便写法

语法

for(初始化语句1;表达式2;语句3){
	循环体
}
  • 先执行语句1
  • 如何判断表达式2
  • 如果为真,执行循环体,如何执行语句3
  • 如果为假,直接退出循环,执行后面的语句

break 和 continue

退出当前的for循环V.S. 退出当前本次循环

label语句

语法

foo: {
	console.log(1);
	break foo;
	console.log('本行不会输出');
}
console.log(2);
面试可能会问这东西是什么?
{
    foo: 1
}

数据类型

数据为什么需要类型

数字与字符串

都是一,为什么要分 1 和 '1'

功能不同

  • 数字是数字,字符串是字符串,要严谨
  • 数字能加减乘除,字符串不行
  • 字符串能表示电话号码,数字不行

存储形式不同

  • JS 中,数字是用64位浮点数的形式存储的
  • JS中,字符串使用类似UTF8形式存储的(UCS-2)

ASCII码:48=0 65=A 97=a

JS中的数据类型

七种(大小写无所谓)

  1. 数字 number
  2. 字符串 string
  3. 布尔 bool
  4. 符号 symbol
  5. 空 undefined
  6. 空 null
  7. 对象 object
  8. bigint(2020年新增类型)
  9. 总结:四基本两空一对象

以下不是数据类型

  • 数组、函数、日期
  • 它们都属于object

数字number

number在js中由64位浮点数组成

写法

  • 整数写法:1
  • 小数写法:0.1
  • 科学计数法:1.23e4
  • 八进制学法(用得少):0123 或 00123 或 0o123
  • 十六进制写法:0x3F 或 0X3F
  • 二进制写法:0b11 或者 0B11

特殊值

  • 正 0 和 负 0:都等于0,要严谨
  • 无穷大:Infinity、+Infinity、-Infinity
  • 无法表示的数字:NaN(Not a Number),但是它是一个数字

64位浮点数

JS数学的存储形式

  • 浮点就是浮动的点,意思就是小数点会乱动
  • 123.456 也可以表示位 1.23456e102,还可以表示为 12345.6e10-2

64位存储一个 number

  • 符号占一位
  • 指数占11位(-1023~1024)
  • 有效数学占 52 位(开头的 1 省略)

范围和精度

范围(忽略符号位)

  • 指数拉满,有效数字拉满,得到最大二进制数字
  • Number.MAX_VALUE: 1.7976931348623157e+308
  • 指数负方向拉满、有效数字最小1,得到最小值
  • Number.MIN_VALUE:5e-324

精度(有效数字)

  • 最多只能到52+1个二进制位表示有效数字
  • 2^53对应的十进制是9后面15个零
  • 所以15位有效数字都能精确表示
  • 16位有效数字如果小于90开头,也能精确表示,但是如果是9110000000000001 就存不下来了

字符串String

每个字符两个字节(阉割版UTF8)

写法

  • 单引号:'你好'
  • 双引号:"你好"
  • 反引号:你好
  • 注意:引号不属于字符串的一部分,就像书名号不属于书名的一部分一样
  • 如果要在单引号里面包含单引号怎么办?

转义

用另一种写法表示你想要的东西

  • 错误写法:'it's ok' JS引擎会认为'it'就结束了,后面的看不懂
  • 正确写法:'it's ok' //这就是转义 "it's ok" it's ok
  • \n 表示换行、\r 表示回车、\t 表示tab制表符、\ 表示 \、\uFFFF 表示对应的Unicode字符、\xFF 表示前 256个 Unicode 字符

多行字符串

如果你想要在字符串里回车

let s = `这样是
可以的
使用反引号就可以做到
`
string.length //可获取字符串的长度
'\n\t\r'.length //长度是3

通过下标读取字符

  • string[index],注意index从0开始,注意index 到 length。

base64编码

加密:window.btoa("123"),解码:window.atob("MTIz")

  • window.btoa ,正常字符串转为base64编码的字符串
  • window.atob, Base64编码的字符串转为原来的字符串
  • 一般用来隐藏招聘启事里面的邮箱:Nzg1ODc5OTg2QHFxLmNvbQ==

布尔boolean

下列运算符会得到bool值

  • 否定运算:!value
  • 相等运算:1==2、1 != 2、 3===4、3 !== 4
  • 比较运算:1 > 2 、1 >= 2、3 < 4、 3 <=4

if 配 bool

  • if语句常常需要判断真假:if(value) else
  • 问题来了:如果value 是 bool 值还好说,如果value不是bool值咋办
  • 1 是真还是假,0 是真还是假,'1' 是真还是假,'0'是真还是假

JS有五个 falsy 值,falsy 就是相当于 false但又不是false的值,分别是 undefined 、null 、0 、NaN 、''。

再加上false 就一共是六个假值

'' 和 ' ' 不是一个玩意,保持严谨

undefined 和 null 两种空类型

这是是JS的原创,也是垃圾的地方。

区别

  • 没有本质区别
  • 细节一:如果一个变量声明了,但是没有复制,那么默认值就是undefined,而不是null
  • 细节二:如果一个函数,没有写return,那么默认return undefined,而不是null
  • 细节三:前端程序员习惯上,把非对象的空值写为undefined,把对象的空值写为 null(但这只是习惯)

变量声明

三种声明方式

  1. var a = 1
  2. let a = 1
  3. const a = 1
  4. a = 1(错误的)

区别

  • var 是过时的、不好用的方式
  • let 是新的,更合理的方式
  • const 是声明时必须赋值,且不能再改的方式
  • 最后这种方式是错误的,不能这样声明

TODO:var 有个变量提升的概念

let声明

规则

  • 遵循块作用域,使用范围不能超出{}
  • 同一个{}中不能重复声明
  • 可以赋值,也可以不赋值
  • 必须先声明在使用,否则报错
  • 全局声明的let变量,不会变成window 的属性
  • for循环配合let 有奇效

const声明

规则:跟let几乎一样,声明时必须马上赋值,而且后续不能再改变这个值。

变量声明的同时指定了值,同时也指定了类型,但是值和类型都可以随意变化

let a = 1
a = 2
a = '字符串'

name 和 'name' 的区别:存的地方不一样,字符串存在stack区。name可以是任何类型,'name'确定是字符串

类型转换

number => string

  • String(n) 或 n + ''

string => number

  • Number(s)
  • parseInt(s) / parseFloat(s)
  • s - 0

x => bool

  • Boolean(x)
  • !!x (取反再取反,相当于原值)

x => string

  • String(x)
  • x.toString()

总结

六种类型:undefined、null、number、string、bool、symbol

这些都是简单类型,只有object叫做复杂类型