变量
类型
值类型
String, Number, Boolean, Undefined, Null数据类型
- 占用空间固定,保存在栈中
- 保存与复制的是值本身
- 使用typeof检测数据的类型
- 基本数据类型是值类型
引用类型
Object数据类型(包括Array, Date等)
- 占用空间不固定,保存在堆中
- 保存与复制的是指向对象的一个指针
- 使用instanceof检测数据的类型
- 使用new()方法构造出的对象是引用型
作用域
全局作用域,函数作用域,块级作用域(ES6)
作用域链
- 内层函数可访问外层函数局部变量
- 外层函数不能访问内层函数局部变量
预解析
预解析
JS代码是在浏览器中的JS解析器执行的。JS解析器在运行JS代码的时候分为两步:预解析和代码执行。
- 预解析:JS引擎会把js里面所有的var和function提升到当前作用域的最前面
- 代码执行:预解析之后按照代码书写的顺序从上往下执行
变量预解析和函数预解析
- 变量预解析(变量提升):把所有的变量声明提升到当前的作用域的最前面。只提升变量声明,不提升赋值操作。【包括函数的表达式声明】
- 函数预解析(函数提升):把所有的函数声明提升到当前的作用域的最前面。只提升函数声明,不调用函数。
数组
基本操作
存取元素
array[index]如list[2]
array[key]如info[name]
增删
- array[新下标] = 赋值
- delete array[index]
- 上述都会直接修改数组,无需重新赋值给原数组
遍历
for (let value of array) { console.log(value) }
for (let index in array) { console.log(array[index]) }
属性
- constructor:引用数组对象的构造函数
- length:数组的长度
- prototype:原型。通过增加属性和方法扩展数组定义
方法
添加 删除
- array.push()在数组末尾添加元素/数组
- array.unshift()在数组头部添加元素
- array.concat()合并两个数组
- array.pop()删除数组最后一个元素
- array.shift()删除数组第一个元素
- 除了concat外,其余方法都会直接修改array,方法的返回值是添加或删除的元素;而concat的返回值是修改后的数组,必须赋值给变量array
let array = [2,4,5,6,3]
delete array[2] // 2, 4, undefined, 6, 3
array[5] = 9 // 2, 4, undefined, 6, 3, 9
let index = 2
array[index] = 8 // 2, 4, 8, 6, 3, 9
let sum = 0
for (let i of array) {
sum+=i
}
console.log(sum)
console.log(array) // 2, 4, 8, 6, 3, 9
let newArray = [5,2]
array.push(7) // 2, 4, 8, 6, 3, 9, 7
array.shift() // 4, 8, 6, 3, 9, 7
array.unshift(1) // 1, 4, 8, 6, 3, 9, 7
array = array.concat(newArray)// 1, 4, 8, 6, 3, 9, 7, 5, 2
array.pop() // 1, 4, 8, 6, 3, 9, 7, 5
console.log(array)
子数组
- splice(起始下标, 要删除的项数可为0, [要插入的项]) 可用于删除任意数量的项/在指定位置添加项/替换任意数量的项
- slice(起始位置, 结束位置)从已有数组中选取部分元素构成新数组
排序
- reverse() 倒序
- sort() 默认按字符串比较;按数值大小比较需要函数支持
// splice(修改位置, 删除项, 添加项) array变化,返回值是子数组
let res
res = array.splice(2, 1, 2, 20) // 8
console.log(array) // 1, 4, 2, 20, 6, 3, 9, 7, 5
// slice(起始位置, 结束位置) array无变化,返回值是子数组
res = array.slice(3,6) // 20, 6, 3
console.log(array) // 1, 4, 2, 20, 6, 3, 9, 7, 5
// sort() reverse() array变化 返回值也是排序后的结果
array.sort() // 1, 2, 20,3,4,5,6,7,9
array.reverse() //9,7,6,5,4,3,20,2,1
转换
- toString() 转换为字符串
- join() 用指定分隔符分割数组并转换为字符串
运算符
算术运算符
+代数求和,字符串连接,数值转换成字符串 -代数减法,字符串转换成数值 *乘法,/除法,%取余
自增与自减
++, --的位置先后会决定进行自增/自减操作和求值的先后顺序
关系运算符
大小关系检测(先后规则)
- 比较中含有数值:转换为代数值比较
- 比较中含有字符串:转换为字符串,逐字符比较Unicode数值
- 无法转换为字符串:返回值为false
- 与NaN比较:返回值为false
等值关系检测
相等比较
- null == undefined (相等)
- NaN与任何数值都不相等包括自身
- 对象== (属于同一对象则相等)
相同比较
- 值类型之间只有数据类型相同、数据值相等,才相等
- 引用类型之间比较引用值(内存地址)
- 值类型和引用类型肯定不同
console.log(3>4);
console.log(3<='3');
console.log('abc'<='abd');
console.log('abc'>undefined);
console.log('abc'<null);
console.log('abc'>NaN);
console.log('-------');
console.log(null == undefined);
console.log(NaN == NaN);
console.log('-------');
let obj1 = {key: 001}
let obj2 = {key: 001}
let obj3 = obj1
console.log(obj1 == obj2) //false
console.log(obj1 === obj2) //false
console.log(obj1 == obj3) //true
console.log(obj1 === obj3) //true
逻辑运算符
短路运算
-
&& 找假 先看第一个表达式的值,如果第一个表达式不是布尔类型,强制转换成布尔类型,转换若后为false,则返回第一个值(不是被强制转换后的值),否则返回第二个值
-
|| 找真 先看第一个表达式的值,如果第一个表达式不是布尔类型,强制转换成布尔类型,转换若后为true,则返回第一个值(不是被强制转换后的值),否则返回第二个值
-
! 非 看表达式的值,如果表达式的值不是布尔类型,强制转换成布尔类型,若为true,则返回false,否则返回true。
其他运算符
-
三元运算符 判断条件? true时执行 : false时执行
-
类型判定预算符typeof
| typeof | p.s. | |
|---|---|---|
| 1 | 'number' | |
| '1' | 'string' | |
| undefined | undefined | |
| true | 'boolean' | |
| Symbol() | 'symbol' | |
| null | 'object' | js的一个bug |
| [] | 'object' | |
| {} | 'object' | |
| console.log | 'function' |
typeof可以返回Number, String, Undefined, Boolean, Symbol类型的数据的数据类型字符串;但对于Null和Object类型,不能使用typeof进行判断,因为Null类型的值null在使用typeof时返回object,并且对于函数还有专门的返回值'function'。
/* 判断变量是否存在。用if(a)在a未声明的时候会报错。使用typeof a,若a未声明,则返回undefined;若a声明了但未赋值,则返回undefined;若声明且赋值,则不会返回undefined */
if ( typeof a != 'undefined') {
console.log('a已存在');
}
- 对象运算符之instanceof instanceof用于检测构造函数的prototype属性是否出现在某个实例对象的原型链上
函数
arguments
当不确定有多少个参数传递时,可以用arguments获取。arguments实际是当前函数的一个内置对象。所有函数都内置了一个arguments对象,arguments 对象中存储了传递的所有实参。
arguments展示形式是一个伪数组,具有length属性,按索引方式存储数据,可以进行遍历。但不具有数组的push和pop方法。
对象
创建
// 1 字面量
let obj1 = {key: value}
// 2 Object对象
let obj2 = new Object()
obj2.key = value
obj2.func = function() {}
// 3 构造函数
function Construct(param) {
this.key = param
}
let obj3 = new Construct(value)
遍历
for (key in obj) {
console.log(key)
console.log(obj.key)
}