## 原型与原型链
* 所有函数都有一个特别的属性:
  * `prototype` : 显式原型属性
* 所有实例对象都有一个特别的属性:
  * `__proto__` : 隐式原型属性
* 显式原型与隐式原型的关系
  * 函数的prototype: 定义函数时被自动赋值, 值默认为{}, 即用为原型对象
  * 实例对象的__proto__: 在创建实例对象时被自动添加, 并赋值为构造函数的prototype值
  * 原型对象即为当前实例对象的父对象
* 原型链
  * 所有的实例对象都有__proto__属性, 它指向的就是原型对象
  * 这样通过__proto__属性就形成了一个链的结构---->原型链
  * 当查找对象内部的属性/方法时, js引擎自动沿着这个原型链查找
  * 当给对象属性赋值时不会使用原型链, 而只是在当前对象中进行操作

## 执行上下文与执行上下文栈
* 变量提升与函数提升
  * 变量提升: 在变量定义语句之前, 就可以访问到这个变量(undefined)
  * 函数提升: 在函数定义语句之前, 就执行该函数
  * 先有变量提升, 再有函数提升
* 理解
  * 执行上下文: 由js引擎自动创建的对象, 包含对应作用域中的所有变量属性
  * 执行上下文栈: 用来管理产生的多个执行上下文
* 分类:
  * 全局: window
  * 函数: 对程序员来说是透明的
* 生命周期
  * 全局 : 准备执行全局代码前产生, 当页面刷新/关闭页面时死亡
  * 函数 : 调用函数时产生, 函数执行完时死亡
* 包含哪些属性:
  * 全局 : 
    * 用var定义的全局变量  ==>undefined
    * 使用function声明的函数   ===>function
    * this   ===>window
  * 函数
    * 用var定义的局部变量  ==>undefined
    * 使用function声明的函数   ===>function
    * this   ===> 调用函数的对象, 如果没有指定就是window 
    * 形参变量   ===>对应实参值
    * arguments ===>实参列表的伪数组

## 继承模式
* 原型链继承 : 得到方法
  ```
  function Parent(){}
  Parent.prototype.test = function(){};
  function Child(){}
  Child.prototype = new Parent(); // 子类型的原型指向父类型实例
  Child.prototype.constructor = Child
  var child = new Child(); //有test()
  ```
* 借用构造函数 : 得到属性
  ```
  function Parent(xxx){this.xxx = xxx}
  Parent.prototype.test = function(){};
  function Child(xxx,yyy){
      Parent.call(this, xxx);//借用构造函数   this.Parent(xxx)
  }
  var child = new Child('a', 'b');  //child.xxx为'a', 但child没有test()
  ```
* 组合
  ```
  function Parent(xxx){this.xxx = xxx}
  Parent.prototype.test = function(){};
  function Child(xxx,yyy){
      Parent.call(this, xxx);//借用构造函数   this.Parent(xxx)
  }
  Child.prototype = new Parent(); //得到test()
  var child = new Child(); //child.xxx为'a', 也有test()
  ```
* new一个对象背后做了些什么?
  * 创建一个空对象
  * 给对象设置__proto__, 值为构造函数对象的prototype属性值   this.__proto__ = Fn.prototype
  * 执行构造函数体(给对象添加属性/方法)
* 执行上下文创建和初始化的过程
  * 全局:
    * 在全局代码执行前最先创建一个全局执行上下文(window)
    * 收集一些全局变量, 并初始化
    * 将这些变量设置为window的属性
  * 函数:
    * 在调用函数时, 在执行函数体之前先创建一个函数执行上下文
    * 收集一些局部变量, 并初始化
    * 将这些变量设置为执行上下文的属性
## 作用域与作用域链
* 理解:
  * 作用域: 一块代码区域, 在编码时就确定了, 不会再变化
  * 作用域链: 多个嵌套的作用域形成的由内向外的结构, 用于查找变量
* 分类:
  * 全局
  * 函数
  * js没有块作用域(在ES6之前)
* 作用
  * 作用域: 隔离变量, 可以在不同作用域定义同名的变量不冲突
  * 作用域链: 查找变量
* 区别作用域与执行上下文
  * 作用域: 静态的, 编码时就确定了(不是在运行时), 一旦确定就不会变化了
  * 执行上下文: 动态的, 执行代码时动态创建, 当执行结束消失
  * 联系: 执行上下文环境是在对应的作用域中的

## 闭包 
* 理解:
  * 当嵌套的内部函数引用了外部函数的变量时就产生了闭包
  * 通过chrome工具得知: 闭包本质是内部函数中的一个对象, 这个对象中包含引用的变量属性
* 作用:
  * 延长局部变量的生命周期
  * 让函数外部能操作内部的局部变量
* 写一个闭包程序
  ```
  function fn1() {
    var a = 2;
    function fn2() {
      a++;
      console.log(a);
    }
    return fn2;
  }
  var f = fn1();
  f();
  f();
  ```
* 闭包应用:
  * 模块化: 封装一些数据以及操作数据的函数, 向外暴露一些行为
  * 循环遍历加监听
  * JS框架(jQuery)大量使用了闭包
* 缺点:
  * 变量占用内存的时间可能会过长
  * 可能导致内存泄露
  * 解决:
    * 及时释放 : f = null; //让内部函数对象成为垃圾对象
    
## 内存溢出与内存泄露
1. 内存溢出
  * 一种程序运行出现的错误
  * 当程序运行需要的内存超过了剩余的内存时, 就出抛出内存溢出的错误
2. 内存泄露
  * 占用的内存没有及时释放
  * 内存泄露积累多了就容易导致内存溢出
  * 常见的内存泄露:
    * 意外的全局变量
    * 没有及时清理的计时器或回调函数
    * 闭包

js-高级(原型与原型链、作用域与作用域链、闭包)的更多相关文章

  1. 第20篇 js高级知识---深入原型链

    前面把js作用域和词法分析都说了下,今天把原型链说下,写这个文章费了点时间,因为这个东西有点抽象,想用语言表达出来不是很容易,我想写的文章不是简单的是官方的API的copy,而是对自己的知识探索和总结 ...

  2. JS高级---构造函数通过原型添加方法,原型的作用: 共享数据, 节省内存空间

    JS高级---构造函数,通过原型添加方法,原型的作用: 共享数据, 节省内存空间 构造函数 //构造函数 function Person(sex, age) { this.sex = sex; thi ...

  3. js高级程序设计(四)变量、作用域和内存问题

    基本类型和引用类型的值 ECMAScript 变量可能包含两种不同数据类型的值:基本类型值和引用类型值.基本类型值指的是 Undefined . Null . Boolean . Number 和 S ...

  4. JS高级程序设计第三版——变量、作用域和内存问题

    JavaScript变量: 由于JavaScript变量松散类型的本质,决定了它只是在特定时间用于保存特定值的一个名字而已.由于不存在定义某个变量必须要保存何种数据类型值的规则,变量的值及其数据类型可 ...

  5. JS高级——原型链

    构造函数 构造函数是特殊的函数,里面没有returen返回值 new的过程中,会自动将对象返回,不需要return new的过程中,会执行函数中的代码,会将创建的对象赋值给构造函数中的this 基本概 ...

  6. JS高级---原型和原型链

    原型和原型链 原型链是一种关系, 实例对象和原型对象之间的关系,关系是通过实例对象中浏览器使用的原型(__proto__)来联系的 自定义构造函数,通过实例化,创建实例对象 实例对象中__proto_ ...

  7. JS高级. 05 词法作用域、变量名提升、作用域链、闭包

    作用域 域,表示的是一个范围,作用域,就是作用范围. 作用域说明的是一个变量可以在什么地方被使用,什么地方不能被使用. 块级作用域 JavaScript中没有块级作用域 { var num = 123 ...

  8. JS高级-原型等概念深入理解

    一 数据类型: 基本(值)数据类型: string number undefined null boolean 对象(引用)类型 [ 查找对象的属性时,会查找原型链 设置属性时,一般在构造函数里面设置 ...

  9. js原型、原型链、作用链、闭包全解

    https://www.2cto.com/kf/201711/698876.html [对象.变量] 一个对象就是一个类,可以理解为一个物体的标准化定义.它不是一个具体的实物,只是一个标准.而通过对象 ...

随机推荐

  1. C# 【一】进程 , 线程 , 微线程 , 同步 , 异步 , 并发 , 并行 , 阻塞 , 非阻塞

    一 理解篇 前言 本文仅仅用作借鉴使用,作者刚入行不久,所以请不小心看到这篇文章的朋友,手下留情. 本文以小故事的形式进行叙述,逻辑不通之处.请理解. 如有错误 ,欢迎指出. 谢谢.          ...

  2. OO Homework One Notes

    系数/指数 过大 溢出(True) eg. - +999999999454554999999 * x ^ -85858554545454545548585858858 x前存在两个符号,与x有空格分离 ...

  3. Android项目实战(一): SpannableString与SpannableStringBuilder(转)

    前言: 曾经在一些APP中的一些类似“帮助”“关于”的界面看过一行文字显示不同的颜色的效果,如下效果: 本软件是一款高.大.上的社区类软件. 一般来说,这应该是由一个TextView来显示的,但是自己 ...

  4. WPS客户端更新日志留着备用

    WPS Office (10.1.0.7520)==========================================新增功能列表------------WPS文字1 拼写检查:新增“中 ...

  5. Android 开源框架Glide的使用

    Glide是一个快速高效的多媒体管理和图像加载的框架,封装了Android平台的多媒体的解码,内存和硬盘缓存等,Glide支持解码.显示视频.图像和GIFs,Glide是基于定制的HttpUrlCon ...

  6. 【Linux】【Java】CentOS7安装最新版Java1.8.191运行开发环境

    1.前言 本来在写[Linux][Apatch Tomcat]安装与运行.都快写完了. 结果...我忘记安装 Java 环境 然后...新开了博客编辑页面. 最后...我的那个没了...没了...真的 ...

  7. ASP.NET Core 入门教程 6、ASP.NET Core MVC 视图布局入门

    一.前言 1.本教程主要内容 ASP.NET Core MVC (Razor)视图母版页教程 ASP.NET Core MVC (Razor)带有Section的视图母版页教程 ASP.NET Cor ...

  8. java使用synchronized与Semaphore解决生产者消费者问题对比

    一.synchronized与信号量Semaphore简介 1.synchronized是java中的关键字,是用来控制线程同步的问题最常用的方法. 2.Semaphore是属于java的一个类,同样 ...

  9. c/c++ 网络编程 bind函数

    网络编程 bind函数 bind的作用是确定端口号. 正常处理都是先bind,然后listen 如果不bind,直接listen,会是什么结果? 内核会自动随机分配一个端口号 例子: #include ...

  10. iOS证书配置与管理

    证书: 证书: 命名 特点 团队管理 开发证书 iOS Development 不与App ID对应 表示拥有开发应用的资格 一般只需一个,通过导出p12文件,分发给其他电脑安装: 生产证书 iOS ...