语法
- 注释,//或/* */
- 标识符(变量、函数、类)
- 第一个字符要求字母、下划线或$
- 区分大小写
- 不能是保留字、关键字、true、false、null
- 语句结尾封号建议写上
- 严格模式:脚本或函数头添加
"use strict";
关键字和保留字
具体可查其他教程
变量
本质:保存任意值的命名占位符,所以声明时不需要指定类型
声明
- var:var message
变量提升:会将函数声明提升到作用域顶部,注意只是声明,直接使用值为undefined
作用域:函数作用域,函数内任何地方定义了,就会在运行前进行变量提升,故而在函数任何地方都能访问到,如果是在全局中,则会成为window对象(global对象)属性
var globalVar = '全局变量'
console.log(window.globalVar);//全局变量
console.log(message);//error!
function testVar(){
console.log(message);//undefined
var message = '初始化';
coonsole.log(message);//初始化
}
- let:let message
与var的区别:
- 变量提升:有提升,但是提升到暂时性死区,变量在没有执行声明之前访问,会提示ReferenceError
- 作用域:块级作用域,注意
每次循环都是新的块级作用域 - 不可重复声明,混用也不行
- 全局声明中不会成为window对象的属性
- for循环中的let声明
//每次循环都会有新的块级作用域,也就是说每次循环的都声明一个新的迭代变量
//此迭代变量由于块级作用域,不能在循环外部访问
for(let i =0; i < 5; i++){
setTimeout(()=>console.log(i),0)
}//0,1,2,3,4
console.log(i)//error!
//而var由于函数级作用域,每次循环其实是一个变量,最后函数访问的都是一个变量,且外部也能访问
for(var i =0; i < 5; i++){
setTimeout(()=>console.log(i),0)
}//5,5,5,5,5
console.log(i)//5
- const:
const message - 与let基本一致
- 必须赋予初始值,且限制的是
值不变,对于对象,则是变量保存的地址不变,对象内部可改变 - for循环中,注意在每次循环中也会重新声明变量,但是不能在循环中改变const的值
//每次循环都会有新的块级作用域,也就是说每次循环的都声明一个新的迭代变量
//不可在迭代中改变值
for(const key in {a:1,b:2}){
console.log(key);
}//a, b
for(const i = 0; i < 5; i++){
setTimeout(()=>console.log(i),0)
}//error!循环内部自增了
数据类型
6种简单类型、1种复杂类型,共七种
- 操作符typeof:
typeof varNmae- 返回值少了null(默认null就是未赋值对象),多了function(区分普通对象)
let varNull = null; function varFunction(){}; console.log(typeof varNull);//object console.log(typeof varFunction);//function - Undefined
- 字面值:undefined(假值)
- 当let、var声明变量但没有初始化的时候,默认赋值了undefined
- 怪异:对于没有声明的变量,调用typeof也会返回undefined
- Null
- 字面值:null(假值)
- typeof null返回object,默认null表示
空对象指针 - undefined由null派生而来,
console.log(null==undefined);//true
- Boolean
-
字面值:ture/false
-
不等同于其他语言,true不等于1,false不等于0,但是0,1可转换成Boolean类型
-
if等控制语句会自动执行其他类型到Boolean类型的转换
-
Boolean()转型函数数据类型 转换为true 转换为false Undefined N/A undefined Number 非0 0、NaN String 非空字符串 "" Object 任意对象,包括{} null
-
- Number
- 字面值:浮点数、整数、NaN(假值)、Infinity(真值)、-Infinity(真值)
- js不显示区分整型和浮点型,但是由于浮点型占据整型空间两倍,js会尽可能将值用整型存储
console.log(10.0 == 10)//true- 取值范围:[Number.MIN_VALUE,Number.MAX_VALUE],超过了就变为Infinity
- NaN:表示不是数值,本来要返回数值的操作失败了(注意不会抛出错误),如0除0
console.log(+0/-0)//NaN console.log(1/-0)//-Infinity-
数值转换Number()- Undefined、Boolean、Null类型,按照真假值映射到0,1
- Number类型返回自身
- String:
- 空字符返回0
- 字符串前后空格忽略,中间是正规数值(可由多个0开头)表示,则返回中间的数值
- 否则返回NaN
- 对象:
- 调用valueOf(),按照上述规则转换,如果是NaN
- 则调用toString()重新转换,即是最后结果
console.log(Number(' 00012.42'))//12.42 console.log(Number(' +12.62 '))//12.62 console.log(Number('j23'))//NaN - parseInt()
- 从第一个非空格字符开始,若该字符不是+-或数值,立即返回NaN
- 往后检测,直到字符串末尾或
非数值字符
- parseFloat()
- 字符多了一个小数点
- String
- 字面量:"",'',``包裹普通字符或转义字符\
- string是
不可变的,当涉及改变时,都是在后台销毁原始字符串,然后将另一字符保存到该变量中,字符串变成值是为了在比较字符串的时候更加高效let stringVar = 'hello'; stringVar = stringVar + 'world';//helloworld,原始的hello喝world都被销毁了 - 模板字面量``
- 其实更像js的表达式,取值后得到字符串
- 会保留内部的换行符号、空格
- 字符串插值${},里面可以是任意表达式
//字符串之间直接就是进行值比较,相比于其他语言更方便 let name="li" let age=19; console.log((name+' '+age)===`${name} ${age}`);//true - 标签函数:普通函数,只是调用方式不一样,用于对模板字面量自定义操作
function tagFunction(strings,...template){ //string是模板中以${}进行分割形成的列表 //template是对每个${}中每个表达式求值后形成的列表 return strings[0] + '<' + template[0] + '>'; } let temp = 'juejing' //注意下面调用方式 console.log(tagFunction`hello ${temp}`)//hello <juejing>- 原始字符串:\n直接显示,而不是换行,使用
String.raw标签函数,注意调用方式
- Symbol
- 字面量:Symbel('描述'),如Symbol(key1)
- 符号值是唯一的,用于确保对象属性唯一标识符
- 创建方式:
let symbolVar1 = Symbol('foo'); let symbolVar2 = Symbol('foo'); //Symbol()里面的值只是用来描述的,可以什么都不传 console.log(symbolVar1 === symbolVar2);//false let symbolGlobal1 = Symbol.for('key1'); let symbolGlobal2 = Symbol.for('key1'); //Symbol.for()会用里面的值检测全局注册表,如果不存在,则注册后返回符号实例,存在则直接取出 console.log(symbolGlobal1 === symbolGlobal2);//true console.log(symbolGlobal1);//Symbol(key1) console.log(Symbol.keyFor(symbolGlobal1))//key1
- Object
- 字面量:{key:value}
- 创建:new constructor()
- 实例属性及方法:
- constructor:创建当前对象的函数
- hasOwnProperty(propertyName):判断当前实例是否存在给定属性(String、Symbol)
- isPrototypeOf(object):判断当前对象是否是object的原型
- propertyIsEnumerable(propertyName):当前属性是否可枚举
- toLocaleString():返回对象的字符串表示
- toString():返回对象的字符串表示
- valueOf():返回对象对应的字符串、数值或布尔值表示,通常与toString相同
操作符
- 一元操作符:++,--,+,-:当用于非Number时,执行数值转换后再使用,+varName等价于Number(varName)
- 位操作符:~,&,|,^,<<,>>(有符号),>>>(无符号)
- 布尔操作符:
- !,同样会执行类型转换,!!varName等价于Boolean(varName)
&&:并不会返回Boolean类型,存在短路,如果第一个为假值,则返回第一个值,不会执行第二个表达式,否则返回第二个表达式求值后的值- ||:与&&类似,只是短路在第一个表达式为真值时
- 乘性操作符:*,/,也会类型转换
- 指数:**,函数Math.pow()
- 加性:+,注意的是如果两个都是number,则数值加,其他则转换成字符串
- 减性:-,类型转换
- 关系比较符:
- <,>,<=,>=:存在类型转换
- 有数值则按照数值比较,如果没有则执行字符串逐个字符比较
- ==,!=:
- 也有类型转换,依然数值优先
- 若两个都是对象,则看是不是同一个对象
- null喝undefined相等,除外与其他都不相等
- NaN与任何值不相等,包括自身
- ===,!==:不存在转换
- <,>,<=,>=:存在类型转换
- 条件运算符:?:
- 赋值与逗号:=,,应用场景:一条语句中声明多个变量
let num1=1,num2=2;
语句
- if,while,do-while,for
- for-in:迭代对象中的非符号键属性,无序
- for-of:遍历迭代元素,如数组集合
- continue-break-标签语句
- continue/break lableName, 其中标签由特定语法声明
lableName:statementlet num=0; outerMost: for(let i = 0;i<10;i++){ for(let j=0;j<10;j++){ if(i == 5&&j==5){ break outerMost } num++; } } console.log(num);//55 - with(不推荐)
- switch-case
- switch()中的值不一定是数值,可以字符串或Boolean,只要case 后面的值与之全等即可
函数
- return不跟值或不写return,不写则默认返回undefine
console.log((()=>{})())//undefined