1.语法
标识符
所谓标识符就是变量、函数、函数参数或者属性的名称。标识符的第一位字符必须是一个字母、下划线、美元符号。命名规则最好使用驼峰命名法,即第一个单词的首字母大写,后面单词的首字母小写。
注释
// 单行注释。 /* */ 多行注释
//单行注释的例子
function test(){
// let a = 1;
//console.log(a);
}
//多行注释的例子
function test(){
/* let a = 1;
console.log(a); */
}
使用严格模式
"use strict"
变量声明
- var: 省略var关键字定义变量,该变量会成为全局变量。
function test(){
a = 123;
}
test()
console.log(a) //123
- 变量提升 使用var声明变量,如果变量的使用在声明之前,程序不会报错
function test(){
console.log(a); //123
var a = 123
}
test()
- let声明:let的声明范围是自带的块级作用域,var的是函数及作用域
//var
if(true){
var a = 123;
console.log(a) //123
}
console.log(a) //123
//let
if(true){
let a = 123;
console.log(a) //123
}
console.log(a) //Uncaught ReferenceError: a is not defined
- 暂时性死区:let与var的一个重要区别就是let声明会存在暂时性死区,而var由于声明提升的特性则不会存在暂时性死区。
- 全局声明:var声明的全局变量会挂载在window对象中,而let声明的变量则不会。
var name = 'test';
let age = 18;
console.log(window.name) //test
console.log(window.age) // undefined
- const声明:与let声明基本一样,不同的是const声明的变量必须 给初始值,并且初始值不能修改(对象属性除外),因为const声明的限制只是针对于它指向变量的引用。
数据类型
ECMAScript有6种简单数据类型(原始类型)和一种复杂数据类型(对象:引用类型),其中原始类型分别为:Number、String、Boolean、Undefined、Null、Symbol;引用类型为Object。 typeof:判断数据类型的操作符,对于Number,String,Boolean,Undefined,Symbol类型typeof都能准确返回对应的字符串,而针对Null类型,typeof返回的是object,因为null是空对象的引用。typeof ‘funcNa6me返回的是‘function’
- 6种原始类型的详解
- Undefined 这里要注意点是,当对未初始化值的变量和未被定义的变量使用typeof时都会返回'undefined'
//未初始化
let aa;
console.log(typeof aa) //undefined
//未定义
console.log(typeof bb) //undefined
这就会造成当变量类型返回undefined是我们不能显而易见的明白变量到底是没有初始化值还是未被定义。
2.Null
null是一个空对象指针,所以在初始化对象时可以用null来初始化,在使用等于操作符(==)来比较undefined和null返回true
console.log(undefined == null) //true
3.Boolean
布尔类型就两种值:false和true,任何值都可以调用Boolean转型函数转为Boolean类型
//Number
console.log(Boolean(123)) //true
//String
console.log(Boolean("123")) //true
//Null
console.log(Boolean(null)) //false
//undefined
console.log(Boolean(undefined)) //false
//object
console.log(Boolean({})) //true
注意:null和{}的区别:上述已经说过null是一个空对象指针,而{}则是一个对象字面量,只是该对象没有任何属性。二者是有本质的区别。
4.Number
//NaN代表应该返回数值类型的操作,但是失败了
console.log(typeof NaN) //number
isNaN()函数,判断是不是NaN,只对NaN返回true,其他都返回false
console.log(isNaN(NaN)) //true
console.log(isNaN(false)) //fale
console.log(isNaN('')) //false
console.log(isNaN(0)) //false
数值转换函数:Number(),parseInt(),parseFloat(),其中Number()函数可以用于任何数据类型,而parseInt()和parseFloat()只用于字符串转数值类型。
- Number()
- 如果对象是一个可被转换为数字的原始值(比如字符串、布尔值等),则返回相应的数字。
- 如果对象是一个 Date 对象,则返回表示日期的毫秒数。
- 如果对象无法转换为数字,则返回
NaN。
console.log(Number(NaN)) //NaN
console.log(Number("123")) //123
console.log(Number("ddjja")) //NaN
console.log(Number(false)) //0
console.log(Number({})) //NaN
const testValue = {
key:123,
stringStr:"sahfkas"
}
console.log(Number(testValue.key)) //123
console.log(Number(testValue.stringStr)) //NaN
console.log(Number(null)) //0
console.log(Number([])) //0
console.log(Number([1,2,3])) //NaN
console.log(Number([2])) //2
- parseInt() 从位置0开始检测,直到字符串末尾或者遇到非数值字符停止。接收一个或者两个参数,一个参数时参数类型为字符串,两个参数时第一个参数为字符串,第二参数为要按照哪种进制来转换,默认为10进制。
console.log(parseInt('Hello')) //NaN
console.log(parseInt('Hello123')) //NaN
console.log(parseInt('123Hello')) //123
console.log(parseInt('123.8')) //123
console.log(parseInt('10',2)) //2 2进制转换
console.log(parseInt('10',8)) //8 8进制转换
console.log(parseInt('0xA',16)) //10 16进制转换
- parseFloat
与parseInt()类似,区别是只能
解析10进制值,不能指定指数。遇到第一个小数点停止。
console.log(parseFloat("123.1.2")) //123.1
5.String
toString()和String():boolean、number、object、string都有toString方法,undefined和null没有此方法,如果二者想转换可以使用String()。
console.log([12,2,3].toString()) //"12,2,3"
console.log(null.toString()) //TypeError: Cannot read properties of null (reading 'toString')
console.log(String(null)) //'null'
console.log(String(undefined)) //'undefined'
模版字符串
let aa =18
console.log(`我的年龄:${aa}`) //我的年龄:18
6.Symbol
是ES6新增的原始类型,特点是唯一、不可变。用处:确保对象属性唯一,避免容易对象内出现重复属性。
Symbol不是构造函数,所以不能使用new关键字实例化,在使用的时候直接 let a = Symbol()即可,也可以增加Symbol标识,便于未来使用该属性。
console.log(typeof Symbol()) //symbol
console.log(Symbol('foo') ==Symbol('foo')) //false
const objkey = Symbol('foo')
const obj = {
[objkey]:42
}
console.log(obj[objkey]) //42
- 注册全局符号
let flag = Symbol.for('foo')
let flag1 = Symbol.for('foo')
console.log(flag ==flag1) //true
- 查询全局符号
let flag = Symbol.for('foo')
let isFlag = Symbol.keyFor(flag) //foo
- 使用Object.defineProperty()和Object.defineProperties()定义属性时使用Symbol
let s1 = Symbol('foo')
let s2 = Symbol('foo')
let s3 = Symbol('foo')
let o = {}
Object.defineProperty(o,s1,{value:'123'})
console.log(o)
Object.defineProperties(o,{
[s2]:{value:123},
[s3]:{value:323}
})
console.log(o)
7.Object
属性:
- constructor:用于创建当前对象的函数;
- hasOwnProperty:判断当前对象实例(不包含原型)上是否存在给定的属性,给定的属性必须是字符串或者是符号。
- isPrototypeOf:判断当前对象是否成为另一个对象的原型。
- propertyIsEnumerable:判断给定的属性是否可以使用
for-in枚举 - toLocaleString():返回对象的字符串表示,该字符串反映对象所在的本地化执行环境
- toString():返回对象的字符串表示
- valueOf():返回对象对应的字符串、数值或者布尔值表示
8.操作符
- 递增与递减的前缀写法和后缀写法区别:
前缀写法是变量值会在求值之前改变,后缀写法则是在求值之后改变
//前缀
let age =18
let oAge = --age+10
console.log(age) //17
console.log(oAge) //27
//后缀
let age = 18
let oAge = age-- +10
console.log(age) //17
console.log(oAge) //28
- 逻辑操作符(与或非):
逻辑非(!)、逻辑与(&&)、逻辑或(||)
流控制语句
- do-while语句:后测试语句,当循环达到一定的条件才会退出并执行while内的语句。
let i =1
do {
i+=2
}while(i<10){
console.log(i) //11
}
- while语句:先测试语句,先检测退出条件再执行循环体内的代码。
let i = 0
while(i<10){
i+=2
console.log(i) //2,4,6,8,10
}
- for语句:先测试语句
- for-in语句:迭代语句,用于枚举对象中
非符号键属性和可枚举属性,返回的结果是无序的
for(const bom in window){
console.log(bom)
}
- for-of语句:严格的迭代语句,用户遍历
可迭代对象的元素 - 标签语句:break和continue语句: 二者都是退出循环。
break是强制退出,强制执行循环后的下一条语句
let num = 0
for(let i =1;i<10;i++){
if(i%5===0){
break;
}
num++;
}
console.log(num) //4
continue退出循环,再次从循环顶部开始执行
let num = 0
for(let i =1;i<10;i++){
if(i%5===0){
continue;
}
num++;
}
console.log(num) //8 因为当i=5时,循环退出,不会执行num++,会再次从循环顶部进行自然循环。
- width语句:
针对一个对象被频繁操作,但是使用width语句会影响性能,严格模式下不能使用,会报错,所以实际开发中不使用。 - switch语句:避免多次使用else if,
比较每个条件值时使用的是全等
let flag =26
switch(flag){
case 25:
console.log(flag);
break;
case 26:
console.log(flag)
break;
}