JavaScript 高级

  • 简述
  • 从 MVC 到 MVVM
  • 再从面向对象编程到原型、作用域链、闭包、递归、DOM 和 BOM
  • MVC & MVVM & oop & prototype & scope chain & closure & recursion & DOM & BOM

MVC

  • 一种编程的‘架构模式’
  • 表现与数据分离
  • Modle : 数据层
  • View : 表现层
  • Controller : 控制层
  • 通过 控制层 将 数据层 与 表现层 揉合在一起展示给用户
  • 也是一种模块化的思想
  • 一个形象的比喻:加工厂
    • 原料:Modle 层
    • 模具:View 层
    • 机床:Controller 层
  • 缺点
    • 增加了结构的复杂性
    • 不适合小型项目的开发
    • 运行效率低

MVVM

  • 典型的代表:AngularJS
  • 核心:不用再关注数据如何呈现在给用户,由框架更新 Module 和 View
  • ng 也提供了自定义的 ViewModel:directive(指令)

oop

  • 在 JavaScript 中已经存在了对象的概念 即: Object
  • 在 JS 中的对象是无序属性的集合
  • 可以通过字面量(直接量) 或 构造函数来定义
  • 实现了代码的复用
  • 而面向对象编程就是一种思想
  • 即:把事物抽象成为一个个对象
  • 再用代码来描述这些对象的特征、行为
  • 例如:每个商品都抽象为一个对象
  • 价格、数量、描述…
  • 在面向对象的三大特征
    • 封装
    • 继承 (prototype)
    • 多态
      • 在 JS 中多态这个特征就不能看成是方法的重载了
      • 只能理解为不同对象有这相同的方法
  • 在 ES6 中引入了 class 的概念
  • class 关键字不过是提供了一种基于原型和构造函数的面向对象的继承方式的语法糖(syntactic sugar)
    • class :类
    • constructor : 类构造器
    • static : 类的静态方法
    • extends :继承父类
    • super :调用父对象上的函数
  • prototype 是实现面向对象继承的机制
    1
    2
    3
    4
    5
    6
    /* 经典的继承模型 */
    function create(obj){
    function F(){}
    F.prototype = obj;
    return new F;
    }

prototype

  • prototype 是实现面向对象编程中继承的一种机制
  • 最终达到代码的复用以及高效的编程
  • 减少内存空间,内存空间的共享
  • 站在不同的角度原型又有不同的解释
    • 站在构造函数的角度 prototype 是构造函数的原型属性
    • 站在对象的角度 prototype 是构造函数实例化出来的那个对象的原型对象
    • 实际上指的都是同一个对象 (原型)
  • 具体讲一下 原型
    • 我们定义了一个字符串可以直接调用 charAt() indexOf() replace() toString() slice() substr() subString() concat()...
    • 我们也没有给这个字符串添加这些方法,那它为什么就可以直接使用呢,这就是继承 String 的原型
    • 继承不是单一的,一个对象可以继承自上一层的,也可以继承上上一层的
    • 即:一个对象可以继承该对象的原型链上的所有成员
  • 原型链
    • 每个对象都有一个原型对象,而该对象的原型对象也有原型对象
    • 于是就形成了一条最终指向 null 的原型链
    • 原型链也是为了原型的有序查找
    • 也体现了继承的层级关系
    • 所有的函数都继承自 Function.prototype
    • 所有的对象都继承自 Object.prototype
    • 函数 Function 也是对象
    • 而对象 Object 也是 Function 创建出来的实例
  • 比较有意思的关系:先有鸡,还是先有蛋
    • 所有的构造函数都是由 Function 创建的,即:Function 创建了 Object
    • 所有的 函数又是对象
    • Function.prototype 相当于是 Function 的基因
    • Object.prototype 相当于是 Object 的基因
    • Function 创建了 Object
    • 而 Function.prototype 又继承自 Object.prototype
  • 对象属性的访问规则
    • 首先在该对象中去查找是否存在该属性
    • 如果不存在就去该对象的原型对象中去查找
    • 如果还是存在就到原型链中去查找
    • 最终找到原型链的末端 null
    • 还是没有的话 直接 undefined

scope chain

  • 作用域
    • 在每一门语言中作用域都是一比较重要的概念,它决定了变量的有权访问
    • 块级作用域
      • 通过代码块 { } 来限定作用范围
    • 词法作用域
      • 在变量定义的时候就已经决定了其作用范围,与代码的执行无关
      • 用函数来划分作用范围
      • 在函数内部可以访问函数外部的变量
    • 当然通过自执行函数可以模拟块级作用域
  • 作用域链
    • 有联系的作用域之间就形成了一个链式结构
    • 作用域链:保证变量的有序访问
  • 变量的查找规则
    • 首先在当前链中查找
    • 如果没有到上一级链中去查找
    • 如果还是没有就到上一级的上一级去查找
    • 就这样一直查找下去,直到找到 0 级
    • 如果还是没有则抛出异常

closure

  • 闭包的基本结构:嵌套的函数
  • 沙箱模式
  • 闭包就是函数外部可以访问函数内部定义的变量
  • 闭包的作用:
    • 跨链访问
    • 数据的私有化
    • 缓存数据
  • 实例:点击不同的按钮显示不同的图片
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    var btns = document.getElementsByTagName('li');
    var img = document.getElementById('img');
    var len = btns.length;
    var imgs = ['1', '2', '3', '4', '5'];
    for(var i = 0; i < len; i++){
    btns[i].onclick = (function(index){
    return function(){
    // console.log(index);
    for(var j = 0; j < len; j++){
    btns[j].className = '';
    }
    img.src = 'imgs/' + imgs[index] + '.jpg';
    this.className = 'current';
    }
    })(i);
    }

recursion

  • 递归:将问题归结为已经解决的问题
  • 什么时候递归
  • 什么时候跳出
  • 求 n! 函数

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    /* 递归 */
    function fn(n){
    if(n < 0) return ;
    if(n === 1) return 1;
    return fn(n - 1) * n;
    }

    /* 递归 + 闭包 */
    var fn = (function(){
    var temp = [];
    return function(n){
    var res = temp[n];
    if(n < 0) return ;
    if(res){
    return res;
    }else {
    n === 1 ? res = 1 : res = arguments.callee(n - 1) * n;
    temp[n] = res;
    return res;
    }
    };
    })();
  • DOM 的深遍历

    1
    2
    3
    4
    5
    6
    7
    8
    9
    function getChild(dom, arr){
    var doms = dom.children;
    for(var i = 0; i < doms.length; i++){
    if(doms[i].children){
    arguments.callee(doms[i], arr);
    }
    arr.push(doms[i]);
    }
    }

DOM

  • 文档对象模型
  • DOM 描述的是网页内容的 API
  • 浏览器会将 文档中的每个标签都渲染成一个 DOM 节点
  • 同时提供了一些操作 DOM 节点的 API
  • click、load、change、mouseover…
  • innerHTML、innerText
  • getElementById()、getElementsClassName()、getElementsByTagName()
  • childNode()、children()
  • nextElementSibling()、nextSibling()
  • firstElementChild()、firstChild()
  • appendChild()、insertBefore()

BOM

  • 浏览器对象模型
  • BOM 描述的是与浏览器进行交互的 API
  • 核心:window
    • alert()、console.log()
    • document
    • location
    • navigator
    • screen

event

  • 事件分为三个阶段:
    • 捕获阶段
    • 目标元素
    • 冒泡阶段
  • 利用事件冒泡进行事件的委托(事件代理)
  • 事件的绑定:
    • addEventListener()
    • attachEvent()
  • 阻止冒泡:
    • e.stopPropagation();
    • e.cancelBubble = true;

jsonp

  • 跨域
  • 只有 get 请求

cors

  • 跨域
  • 跨站资源请求
  • 支持所有的请求方式
  • 在请求头信息中添加 Origin 字段
文章目录
  1. 1. JavaScript 高级
    1. 1.0.1. MVC
    2. 1.0.2. MVVM
    3. 1.0.3. oop
    4. 1.0.4. prototype
    5. 1.0.5. scope chain
    6. 1.0.6. closure
    7. 1.0.7. recursion
    8. 1.0.8. DOM
    9. 1.0.9. BOM
    10. 1.0.10. event
    11. 1.0.11. jsonp
    12. 1.0.12. cors