数据类型
JS 的基本数据类型有6种:Number、String、Boolean、Undefined、Null、Symbol(ES6新增)
JS引用数据类型:Object(Object、Function、Array)
- 类型区别
- 基本类型数据存储在栈中,引用类型数据存储在堆中,栈中存储的变量,是指向堆中的引用地址;
- 基本类型数据按值访问,引用类型数据按引用访问;
- 复制变量不同;
- 函数传参都是按值传递,基本类型数据拷贝的是值,引用类型数据拷贝的是引用地址
- 类型判断:
typeof
- 除了null外都显示正确的类型(JS最初版本32位系统原因);
- 引用类型除了函数都返回 ‘object’ ;
Object.prototype.toString.call(xx)
Object.prototype.toString.call(1) // "[object Number]"
- 类型转换
- 转Boolean:在条件判断时,除了 undefined , null , false , NaN , ‘’ , 0 , -0 ,其他所有值都转为 true ,包括所有对象;
- 对象转基本类型
原型和原型链
我们创建的每个函数都有 prototype 属性,这个属性指向函数的原型对象。原型对象的用途是包含可以由特定类型的所有实例共享的属性和方法。
在默认情况下,所有原型对象都会自动获得一个== constructor ==属性,这个属性包含一个指向 prototype 属性所在函数的指针。
当调用构造函数创建一个新实例后,该实例的内部将包含一个指针,指向构造函数的原型对象(可以通过实例的__proto__ 来访问构造函数的原型对象)。
- 实例.proto === 构造函数.prototype
每个构造函数都有一个原型对象,原型对象都包含一个指向构造函数的指针,而实例都包含一个可以指向原型对象的内部指针(可以通过 proto 访问)。
对象可以通过 proto 来寻找不属于该对象的属性, proto 将对象连接起来组成了原型链。
-
new 的过程
新生成一个对象 - 链接到原型 - 绑定this - 返回新对象 -
instanceof
A instanceof B:如果B函数的显式原型对象在A对象的原型链上,则返回true,否则返回false。
this指向问题
谁调用它,this就指向谁
- ES6箭头函数:this指向上下文绑定的this(箭头函数无this!!!)
- 全局环境下,this指向window
- new对象中,this指向新对象
- call、apply、bind调用时,this指向的就是指定对象(常用于更改this指向)
JS 执行上下文栈和作用域以及作用域链
JS执行上下文过程中,需要创建变量对象,创建作用域链,确定this的值,从而实现下一步动作。
- 类型:
- 全局执行上下文
- 函数执行上下文
- eval执行上下文
- 变量提升和函数提升
生成上下文时,显示创建/定义阶段,开辟内存空间,函数是整个存入,变量只是声明且复制undefined;函数优先于变量提升哦~
- 作用域
全局、块级、函数三类作用域环境。 - 作用域链
从当前作用域层层向上寻找某个变量,知道找到全局作用域,就结束。这种层层关系即被成为作用域链。
var、let、const
- let/const 定义的变量不会出现变量提升,而 var 定义的变量会提升。即let/const有暂时性死区的问题,let/const 声明的变量,在定义之前都是不可用的。如果使用会抛出错误。;
- 相同作用域中,let 和 const 不允许重复声明,var 允许重复声明;
- const 声明变量时必须设置初始值;
- const 声明一个只读的常量,这个常量不可改变;
- let/const 声明的变量仅在块级作用域中有效。而 var 声明的变量在块级作用域外仍能访问到;
闭包
闭包是指有权访问另一个函数作用域内的变量的函数。创建闭包最常用的方式就是创建一个函数(函数 A 返回了⼀个函数 B,并且函数 B 中使⽤了函数 A 的变量,函数 B就被称为闭包)。
简单说来:函数+变量=闭包
function foo() {
var a = 2;
return function fn() {
console.log(a);
}
}
let func = foo();
func(); //输出2
闭包作用
- 能有访问函数定义时所在的作用域(防止被回收);
- 私有化变量
- 模拟块级作用域
- 创建模块
** 闭包缺点**
- 闭包容易造成内存泄漏(因为 IE。IE 有 bug,IE 在我们使用完闭包之后,依然回收不了闭包里面引用的变量。)
浅拷贝、深拷贝
拷贝其实就是赋值操作。常见的深拷贝方法
- JSON.parse(JSON.stringfly(obj))
- 递归赋值
function deepClone(obj, hash = new WeakMap()) {
//递归拷贝
if(obj instanceof RegExp) return new RegExp(obj);
if(obj instanceof Date) return new Date(obj);
if(obj === null || typeof obj !== 'object') {