基础总结深入
数据类型
基本数据类型 Number String Boolean undefind null
引用数据类型 Object Array Function
typeof区分数据类型 数值 字符串 布尔值 undefind function 不区别null 一般对象和数组
null是object 函数是function 一般对象是object
instanceof 专门用来区别对象的数据类型
表达式: A instanceof B * 如果B函数的显式原型对象在A对象的原型链上, 返回true, 否则返回false
变量
赋值===>分为值赋值赋的是本身 对象赋值赋的是内存地址
内存
1. 内存生命周期 1). 分配需要的内存 2). 使用分配到的内存 3). 不需要时将其释放/归还
对象
多种数据类型的集合体
对象的属性一定是字符串;所以省略
通过对象["属性名"]可以访问属性
函数
函数也是个对象
函数的形式: 自调用 回调函数 构造函数
封装的特定功能
提高代码复用
便于阅读和复用
可以调用
函数对象可以函数名.属性
回调函数
回调函数
条件:自己定义的
没有直接调用
在特定条件下 执行
DOM事件函数 定时器事件函数 ajax事件函数
立即执行函数
当执行当前js代码时自动执行
(function (i) {
var a = 4
function fn() {
console.log('fn ', i+a)
}
fn()
this
一个关键字
this代表当前函数对象 在执行的时候才动态绑定 自调用的时候是window
this的三种指向:1.指向this所在函数的直接调用者,2.new的时候,指向new出来的对象,3.事件中指向当前的出发对象
面向对象高级
函数是在调用的时候看
函数高级
原型
原型就是一个对象
函数的propotype属性
每个函数都有prototype 默认指向一个显示原型对象
原型对象中有个constructor 指向函数对象
每个实例对象都有一个__proto__属性 指向一个隐士原型对象
作用:当定义一个公共的方法时可以放在原型对象上
构造函数的显示原型对象===当前构造函数实例对象的隐士原型对象
对象分为两种
普通的对象都可以是new Object出来的
显示原型对象是实例对象
函数对象 不能在点方法了只能点属性
实例对象 能点方法也能点属性
原型链
当查找对象的属性的时候先在自身找;如果没有沿着_proto_找;proto就是原型链
当给对象属性赋值时不会使用原型链, 而只是在当前对象中进行操作
找变量会沿着作用链找
执行上下文(预解析)
全局执行上下文
函数执行上下文
先看有没有调用函数;然后再执行上下文
定义 :在js引擎执行js代码之前会创建执行环境
工作内容
1创建空对象
2变量提升(收集var function 参数)
3 创建作用域链 作用域是代码定义的时候定义
4 确认this指向 没有创建对象的时候this是window 创建对象this只的是当前对象
函数自执行的this是window
在全局代码执行前;js引擎会创建一个栈来存储所有的执行上下文
在全局执行上下文(window)确定后;将其添加到栈中 注:变量提升
在当前函数执行完毕后;将栈顶对象移除
当所有代码执行完毕后;栈中只剩下window
作用域
全局作用域
代码执行的时候存在 关掉浏览器销毁
函数作用域
函数执行的时候开始 函数执行完毕销毁
作用域链
查找当前变量先从当前作用域找;如果没有找到去外层找;如果没有就报错
闭包
定义 内部函数引用外部函数变量(在浏览器中显示Closure)
条件 函数嵌套 内部函数引用外部函数数据
作用 延长外部函数的生命周期
从外部访问内部函数数据
将内部函数作为返回值
缺点 :占用内存
解决:能不用就不用了 用完内部函数等于null
提示: 同步是阻塞后面的代码 通过alert()能够实现 异步 一定有对应的回调函数
对象的创建模式
1:Object构造函数模式
先创建Object对象;在添加属性/方法
适用场景:期初不确定对象内部数据
问题:语句太多
2字面量模式
使用{}创建对象;同时制定属性/方法
使用场景:期初不确定对象内部数据
问题:创建多个对象
3 工厂模式
通过工厂函数创建
场景:避免重复代码;创建多个对象
问题:对象没有具体类型;都是Object类型
function createPerson(name, age) {
var p = {
name: name,
age: age,
setName: function (name) {
this.name = name
}
}
return p
}
4自定义构造函数
通过new来创建
场景:需要创建多个类型确定的对象
问题:每个对象都有相同数据;浪费内存
5构造函数+原型组合
先自定义构造函数;属性在函数中 变换的方法添加到原型上
场景;创建多个类型确定的对象
function Person (name, age) {
this.name = name
this.age = age
}
//在函数内部定义方法 new多少实例就new多少方法占用内存所以放到原型上
Person.prototype.setName = function (name) {
this.name = name
}
原型连继承
1 先给父类型构造函数
2在给父类行原型添加方法
3 定义子类型构造函数
4创建父类型的对象赋值给与子类型的原型
5 将子类型原型的构造函数设置为子类型
6 给子类型原型添加方法
7 创建子类型对象;可调用父类型方法
F1.prototype.say=function () {
console.log("我是父类")
}
function F2() {
}
//父类的实例成为子类的原型
F2.prototype=new F1()
//以上步揍会导致子类原型构造器属性丢失;所以需要手动添加构造器属性
F2.prototype.constructor=F2
F2.prototype.say2=function () {
console.log("我是子类的方法")
}
var f2=new F2()
f2.say()
f2.say2()
借助构造函数继承
先定义父类构造函数
定义子类构造函数
在子类构造函数调用父类构造函数
function F(name,age) {
this.name=name,
this.age=age
}
function F2(name,age) {
//在子类的构造函数调用父类的构造函数
//通过call来改变this的指向 第一个参数是this第二个参数是传递的参数 apply也是改变this 的指向 但是传递的参数是数组
F.call(this,name,age)
}
var f2=new F2("张三",20)
console.log(f2)
原型链继承加构造函数继承
属性在构造函数中继承方法在原型链上集成
垃圾回收机制
作用域 全局/局部
局部作用域是在函数定义的时候产生,会一直存在销毁的是上下文
垃圾回收机制是循环的机制
计数清除
标记清除
线程机制与事件循环机制
进程和线程
进程是一个程序
线程是程序执行的一个完整流程
3. 进程与线程 * 一个进程中一般至少有一个运行的线程: 主线程 * 一个进程中也可以同时运行多个线程, 我们会说程序是多线程运行的 * 一个进程内的数据可以供其中的多个线程直接共享 * 多个进程之间的数据是不能直接共享的
单线程
特点:
自上而下执行
所有的代码都在主线程执行
对于异步交给浏览器管理模块
同步代码 同步任务会导致阻塞
代表:alert() console.log()
异步代码 定时器;事件回调
事件循环模型
代码分类
同步代码(初始化执行的代码)
异步代码(毁掉执行的代码)
事件循环机制
所有的代码都在主线程执行
同步代码加载及执行
异步代码交给浏览器管理模块
管理模块会监视异步代码是否满足条件;如果满足放入对应的回调队列callback queue (在进入浏览器管理模块时就开始看条件了)
主线程的同步代码执行完通过event loop 事件轮训机制询问callback queue
查看是否有克制行函数;如果有将回调能够到主线程执行
其他
H5规范提供了js分线程实现 取名Web Workers
不足:worker不能操作dom 不能跨域加载js 不是所有浏览器都支持这个新特征