学习回顾No.4

JS

  • 基本(值)类型:String、Number、boolean、undefined、null
  • 对象(引用)类型:Object、Function、Array
  • 判断:typeof、instanceof、===
  • undefined代表定义未赋值
  • null定义并赋值了,只是值为null
  • 什么时候赋null
    1. 初始时,表示将要赋值为对象
    2. 结束前,让指向的对象成为垃圾对象
  • 数据的类型:基本类型、对象类型
  • 变量的类型(变量内存值的类型)
  • 基本类型:保存就是基本类型的数据
  • 引用类型:保存的是地址值
  • 内存分类
  • 栈:全局变量/局部变量
  • 堆:对象
  • 必须用[‘属性名’]方式
    1. 属性名包含特殊字符:-、空格
    2. 变量名不确定
  • 回调函数:你定义的,没有调用,最终执行了
  • 常见的回调函数:dom事件、定时器、ajax请求、生命周期
  • Immediately-Invoked Function Expression - 匿名函数自调用
  • 作用:隐藏实现,不会污染外部(全局)命名空间
  • 每个函数function都有一个prototype,即显式原型,默认指向一个空的object对象
  • 每个实例对象都有一个__ proto__,可称为隐式原型,默认为构造函数的prototype属性值
  • 对象的隐式原型的值为其构造函数的显式原型的值
  • 原型链
  • 访问一个对象的属性时,先在自身属性中找,再沿着__ proto__向上查找,最终没找到,返回undefined
  • 别名:隐式原型链
  • 作用:查找对象的属性(方法)
  • Object.__ proto__ === Function.prototype; //true
  • Function.__ proto__ === Function.prototype; //true
  1. 函数的显式原型指向的对象默认是空Object实例对象(但Object不满足) Function.prototype instanceof Object; //true Object.prototype instanceof Object; //false
  2. 所有函数都是Function的实例(包含Function)
  3. Object的原型对象是原型链尽头 Object.prototype.__ proto__; //null
  • instanceof表达式: A instanceof B
  • 若B函数的显式原型对象在A对象的原型链上,返回true,否则返回false
  1. 变量声明提升:通过var定义(声明)的变量,在定义语句之前就能访问到 值:undefined

  2. 函数声明提升:通过function声明的函数,在之前就可以直接调用 值:函数定义(对象)

  3. 全局执行上下文:在执行全局代码前将window确定为全局执行上下文,对全局数据进行预处理

  4. 函数执行上下文:在调用函数,准备执行函数体之前,创建对应的函数执行上下文对象,对局部数据进行预处理

先提升后赋值

var c = 1
function c(c){
	console.log(c)
	var c = 3
}
c(2) //报错
var c 
function c(c){
	console.log(c)
	var c = 3
}
c = 1
c(2)

作用域

  1. 它是静态的(相对于上下文对象),在编写代码时就确定了
  2. 分类:全局作用域、函数作用域、块作用域(ES6)
  3. 作用:隔离变量,不同作用域下同名变量不会有冲突

闭包


  • 当一个嵌套的内部(子)函数引用了嵌套的外部(父)函数的变量(函数)时,就产生了闭包
  • 理解一:闭包是嵌套的内部函数
  • 理解二:包含被引用变量(函数)的对象
  • 注意:闭包存在于嵌套的内部函数中

常见的闭包

  1. 将函数作为另一个函数的返回值
  2. 将函数作为实参传递给另一个函数调用

闭包的作用

  1. 使用函数内部的变量在函数执行完后,仍然存活在内存中(延长了局部变量的生命周期)
  2. 让函数外部可以操作(读写)到函数内部的数据(变量/函数)

闭包的生命周期

  1. 产生:在嵌套内部函数定义执行完时就产生了(不是在调用)
  2. 死亡:在嵌套内部函数成为垃圾对象时

闭包存在的关键点

  • 使用一个变量接受嵌套的内部函数,让它在执行完之后不成为垃圾对象

闭包的应用:定义JS模块

  1. 具有特定功能的js文件
  2. 将所有的数据和功能都封装在一个函数内部(私有的)
  3. 只向外暴露一个包含n个方法的对象或函数
  4. 模块的使用者,只需要通过模块暴露的对象调用方法来实现相应的功能

闭包的缺点及解决

  • 缺点:
    1. 函数执行完后,函数内的局部变量没有释放,占用内存时间会变长
    2. 容易造成内存泄露
  • 解决:
    1. 能不用闭包就不用
    2. 及时释放

内存溢出

  1. 一种程序运行出现的错误
  2. 当程序运行需要的内存超过了剩余的内存时,就会抛出内存溢出的错误

内存泄露

  1. 占用的内存没有及时释放
  2. 内存泄露积累多了就容易导致内存溢出

常见的内存泄露

  1. 意外的全局变量
  2. 没有及时清理的计时器或回调函数
  3. 闭包

对象创建模式


Object构造函数模式

  • new Object()
  • 问题:语句太多

对象字面量模式

  • 使用{}创建,同时指定属性/方法
  • 问题:如果创建多个对象,有重复代码

工厂模式

  • 通过工厂函数动态创建对象并返回
  • 问题:对象没有一个具体的类型,都是object类型

自定义构造函数模式

  • 通过new创建对象
  • 问题:每个对象都有相同的数据,浪费内存

构造函数+原型的组合模式

  • 套路:自定义构造函数,属性在函数中初始化,方法添加到原型上
  • 适用场景:需要创建多个类型确定的对象

继承模式


原型链继承

  1. 定义父类型构造函数
  2. 给父类型原型添加方法
  3. 定义子类型的构造函数
  4. 创建父类型的对象赋值给子类型的原型
  5. 将子类型原型的构造属性设置为子类型
  6. 给子类型原型添加方法
  7. 子类型对象,可调用父类型的方法

关键:子类型的原型为父类型的一个实例对象

借用构造函数继承(假的)

  1. 定义父类型构造函数
  2. 定义子类型构造函数
  3. 在子类型构造函数中调用父类型构造函数

关键:在子类型构造函数中通用call()调用父类型构造函数

原型链+借用构造函数的组合继承

  1. 利用原型链实现对父类型对象的方法继承
  2. 利用super()借用父类型构造函数初始化相同属性

进程与线程

  1. 进程:程序的一次执行,它占用一片独有的内存空间
  2. 线程:CPU的基本调度单位,是程序执行的一个完整流程。
  3. 一个进程中一般至少有一个运行的线程:主线程。
  4. 一个进程中也可以同时运行多个线程,我们会说程序是多线程运行的。
  5. 一个进程内的数据可以供其中的多个线程直接共享
  6. 多个进程之间的数据是不能直接共享的

定时器

  1. 定时器并不能保证真正定时执行
  2. 一般会延迟一丁点,也可能延迟很长时间
  3. 回调函数在主线程执行的,js是单线程的
  4. 是事件循环模型实现

JS是单线程的

  1. setTimeout()的回调函数是在主线程执行的
  2. 定时器回调函数只有在运行栈中的代码全部执行完后才有可能执行
  3. Js的单线程,与它的用途有关
  4. 作为浏览器脚本语言,主要用途是与用户互动,以及操作DOM
  5. 这决定了它只能是单线程,否则会带来很复杂的同步问题
  6. 代码分类:初始化代码,回调代码
  7. js引擎执行代码的基本流程:a. 先执行初始化代码:包含一些特别代码,回调函数(异步执行) b. 设置定时器 c. 绑定监听 d. 发送ajax请求 e. 后面在某个时刻才会执行回调函数

事件循环模型

  1. 初始化执行代码(同步代码) 回调执行代码(异步代码)
  2. 初始化代码 => 回调代码
  3. 模型的2个重要组成核心:事件管理模块、回调队列
  4. 模型的运转流程:a.执行初始化代码,将事件回调函数交给对应模块管理 b.当事件发生时,管理模块会将回调函数及其数据添加到回调队列中 c.只有当初始化代码执行完后,才会遍历读取回调队列中的回调函数执行

else

  1. H5规范提供了js分线程的实现,取名为Web Workers
  2. 相关API
  3. Worker:构造函数,加载分线程执行的js文件
  4. Worker.prototype.onmessage:用于接收另一个线程的回调函数
  5. Worker.prototype.postMessage:向另一个线程发送信息
  6. 不足:Worker内代码不能操作DOM(更新UI)、不能跨域加载JS、不兼容
  7. 浏览器内核检测工具:https://ie.icoa.cn/

你可能感兴趣的:(学习,原型模式,javascript)