深入了解 JS(2)

91 阅读4分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第6天,点击查看活动详情

前端最重要的三大基础(前端三剑客),HTML CSS JAVASCRIPT,学习前端必学的三门基础知识点。

特别是JavaScript,这个基础必须是要最扎实的,不管在哪个项目中,前端都不会离开他的,所以我们要打牢它的基础。学习完基础后JavaScript的深入学习也是必不可少的,这节开始讲一下函数相关:

  • 原型与原型链
  • 执行上下文与执行上下文栈
  • 作用域与作用域链
  • 闭包

同期回顾:

深入了解 JS(1)

原型与原型链

1. 原型

image.png

  • 函数的prototype属性
    • 每个函数都有一个prototype属性, 它默认指向一个Object空对象(即称为: 原型对象)
    • 原型对象中有一个属性constructor, 它指向函数对象
  • 给原型对象添加属性(一般都是方法)
    • 作用: 函数的所有实例对象自动拥有原型中的属性(方法)

image.png

2. 显式原型与隐式原型

  • 每个函数function都有一个prototype,即显式原型
  • 每个实例对象都有一个__proto__,可称为隐式原型
  • 对象的隐式原型的值为其对应构造函数的显式原型的值
  • 内存结构

image.png

  • 总结:
    • 函数的prototype属性: 在定义函数时自动添加的, 默认值是一个空Object对象
    • 对象的__proto__属性: 创建对象时自动添加的, 默认值为构造函数的prototype属性值
    • 程序员能直接操作显式原型, 但不能直接操作隐式原型(ES6之前)
    • 原型属性问题
    • 读取对象的属性值时: 会自动到原型链中查找
    • 设置对象的属性值时: 不会查找原型链, 如果当前对象中没有此属性, 直接添加此属性并设置其值
    • 方法一般定义在原型中, 属性一般通过构造函数定义在对象本身上

3. 探索instanceof

  • instanceof是如何判断的?
    • 表达式: A instanceof B
    • 如果B函数的显式原型对象在A对象的原型链上, 返回true, 否则返回false

4. 执行上下文与执行上下文栈

  • 变量提升与函数提升

    • 变量声明提升

      • 通过var定义(声明)的变量, 在定义语句之前就可以访问到
      • 值: undefined
    • 函数声明提升

      • 通过function声明的函数, 在之前就可以直接调用
      • 值: 函数定义(对象)
  • 执行上下文

    • 代码分类(位置)

      • 全局代码
      • 函数代码
    • 全局执行上下文

      • 在执行全局代码前将window确定为全局执行上下文
      • 对全局数据进行预处理
      • var定义的全局变量==>undefined, 添加为window的属性
      • function声明的全局函数==>赋值(fun), 添加为window的方法
      • this==>赋值(window)
      • 开始执行全局代码
    • 函数执行上下文

      • 在调用函数, 准备执行函数体之前, 创建对应的函数执行上下文对象

      • 对局部数据进行预处理

        • 形参变量==>赋值(实参)==>添加为执行上下文的属性

        • arguments==>赋值(实参列表), 添加为执行上下文的属性

        • var定义的局部变量==>undefined, 添加为执行上下文的属性

        • function声明的函数 ==>赋值(fun), 添加为执行上下文的方法

        • this==>赋值(调用函数的对象)

      • 开始执行函数体代码

5. 作用域与作用域链

image.png

  • 理解
    • 就是一块"地盘", 一个代码段所在的区域
    • 它是静态的(相对于上下文对象), 在编写代码时就确定了
  • 分类
    • 全局作用域
    • 函数作用域
    • 没有块作用域(ES6有了)
  • 作用
    • 隔离变量,不同作用域下同名变量不会有冲突
  • 作用域链
    • 理解

      • 多个上下级关系的作用域形成的链, 它的方向是从下向上的(从内到外)
      • 查找变量时就是沿着作用域链来查找的
    • 查找一个变量的查找规则

      • 在当前作用域下的执行上下文中查找对应的属性, 如果有直接返回, 否则进入2

      • 在上一级作用域的执行上下文中查找对应的属性, 如果有直接返回, 否则进入3

      • 再次执行2的相同操作, 直到全局作用域, 如果还找不到就抛出找不到的异常

闭包的内容比较多,比较重要,我们下一节再讲它