作用域、上下文、闭包、原型、继承

JS运行过程分为两个步骤:
1、预编译过程:执行上下文区域/全局词法环境
时间:执行代码之前完成
所做的事情:1)把所有var方式定义的变量全部存入上下文,赋值为undefine
2)把所有函数声明方式定义的函数名和函数体存入上下文
3)this运行时确定(预编译确定)
覆盖问题:
1)声明函数方式覆盖:后面的会覆盖前面的
2)后面的函数如果是表达式方式定义的,和属性var方式定义是一样的性质,会忽略
2、执行过程
时间:预编译完毕后的操作
所做的事情:1)把所有变量附上值
2)声明方式定义的函数不会再管了,只会处理表达式方式定义的函数

JS上下文栈
什么是表达式:只要代码中出现了基本的运算符号就是表达式
注意:寻找自由变量的时候,会从上下文栈中依次寻找,如果找到全局上下文还是寻找不到,就会报错

作用域:没有块级所用于,只有全局作用域和函数作用域

作用域、上下文、闭包、原型、继承

什么是闭包
闭包就是指外部能够随意读取其他函数内部变量的函数
也可以理解成“定义在一个函数内部的函数”
闭包是将函数内部和函数外部连接起来的桥梁
闭包作用
可以读取函数内部的变量,减少全局变量定义
减少函数传递参数的数量
让函数内部变量的值始终保持在内存中,不会在函数调用完毕后被自动清除

闭包使用注意事项
闭包使用父函数变量时候,只是个引用,而不是复制
父函数每调用一次,会产生不同的闭包
闭包中循环的问题
函数声明和表达式的区别:
表达式是由运算元和运算符(可选)构成,并产生运算结果的语法结构。
(function {})是表达式
function {}是函数声明.
自执行函数格式:
原理:括弧()和JS的&&,异或,逗号等操作符能在函数表达式和函数声明上消除歧义
方式1:调用函数,得到返回值。强制运算符使函数调用执行
方式2:调用函数,得到返回值。强制函数直接执行再返回一个引用,引用再去强制执行
方式3:通过一些操作符,来把声明强制转化为表达式,并执行

作用域、上下文、闭包、原型、继承

prototype原型

任何函数都是对象 任何函数都会有个默认自带属性:prototype,称之为原型 prototype指向的是一个对象,对象称之为原型对象 原型对象内部封装了唯一一个默认属性constructor,称之为原型构造器 原型构造器指向的是当前函数本身

原型链

作用域、上下文、闭包、原型、继承

浅拷贝
原理:初步实现其中一个对象的所有属性和函数都拷贝到另外一个对象中
问题:只拷贝了基本数据类型,引用类型只是发生类地址的赋值,导致多个对象共享一个地址

深拷贝

原理:通过递归,不仅将原对象的各个属性逐个复制出去,而且将原对象各个属性所包含的对象也依次采用深复制的方法递归复制到新对象上
JS继承实现
定义:一个类中直接拥有另外一个类中的属性和方法的过程
注意:JS中的继承不伦不类,大不要以高级面向对象语言的思维来思考JS继承
JS中的继承方式多种,具体分类如下
1)对象继承:深度拷贝完成继承
2)类的继承:call/apply方式、原型链方式、混合模式、桥接混合模式

继承方式1:拷贝继承
子类构造函数中创建父类对象
把父类对象所有属性拷贝到子类构造函数原型中
给子类添加自己的属性和方法

缺点:
子类所有对象的原型(父类对象)共享,如果修改任何一个对象的父类引用内容,所有对象会同步
效率低、占用内存大,创建一个子类对象同时,需要创建一个父类对象
无法继承父类不可枚举的属性和方法
作用域、上下文、闭包、原型、继承

继承方式2:原型链(prototype chaining)
原理:把父类的对象作为子类的原型
优势:
编写简单、容易理解
父类的属性和原型属性子类都能访问
缺点:
子类所有对象的原型(父类对象)共享,如果修改任何一个对象的父类引用内容,所有对象会同步
创建子类实例时候,没有办法对父类构造方法内部初始化属性
作用域、上下文、闭包、原型、继承

继承方式3:构造函数继承
在子类构造函数中,通过call方法调用父类构造函数
在调用父类构造函数时候,同时初始化了子类构造函数属性
原理:相当于复制父类的实例属性给子类

优势:解决了父类原型数据共相问题,并可以初始化参数
可以实现多重继承
缺点:实例跟父类没关系,脱离了继承的本质
只能继承父类实例属性和方法,不能继承原型属性和方法
作用域、上下文、闭包、原型、继承

继承方式4:混合方式继承(原型链+构造方法)
在子类构造函数中,通过call方法调用父类构造函数
子类的原型指向父类对象实例

优势:可以继承父类示例属性和方法,也能继承原型属性和方法
既是子类实例也是父类实例
缺点:调用了2次父类构造方法,增大了开销
作用域、上下文、闭包、原型、继承

继承方式五:混合桥接式继承(推荐使用)
在子类构造函数中,通过call方法调用父类构造函数,引入所有属性
定义一个空的对象,作为桥接
子类原型指向空的对象,空的对象原型指向父类原型
作用域、上下文、闭包、原型、继承