JavaScript高级(一)

js高级

函数

函数

  1. 函数也是对象
  2. 函数具备行为,可以被调用
  3. 用来减少代码量,复用,隔离变量,减少命名污染

函数分类

  1. 普通的函数
  2. 构造函数
  3. IIFE(匿名函数自调用)
  4. 回调函数(事件的回调,定时器的回调)

函数的this

  1. 理解this:
    • 关键字
    • 变量
  2. this的指向问题
    • 函数this不是函数定义的时候决定的
    • 函数this指向谁看如何调用当前的函数
  3. this指向分类
    • 函数自调用: window
    • 构造函数(new function): 当前构造函数的实例对象
    • 对象.方法(): 对象本身
    • fun.call/apply(指定的对象): 指定的对象
<!--
1. this是什么?
  * 一个关键字, 一个内置的引用变量
  * 在函数中都可以直接使用this
  * this代表调用函数的当前对象
  * 在定义函数时, this还没有确定, 只有在执行时才动态确定(绑定)2. 如何确定this的值?
  * test()
  * obj.test()
  * new test()
  * test.call(obj)
前置知识:
  * 本质上任何函数在执行时都是通过某个对象调用的
-->

<script type="text/javascript">
  
  
  
  console.log(this); // window
  console.log(window);
  // 函数this的指向问题
  function fun() {
     
    console.log(this);
  }

  fun(); // window
  new fun(); // 当前构造函数的实例对象
  var obj = {
     
    fun: fun
  }
  obj.fun(); // obj

</script>

原型

什么是原型对象

1. 每个函数都有一个prototype属性,该属性指向的是原型对象(显示原型对象)
2. 每个实例对象身上都有一个__proto__属性,该属性指向的也是原型对象(隐式原型对象)
3. 构造函数的显示原型 === 当前构造函数实例对象的隐式原型对象
4. 原型对象的本质: 普通的Object实例

什么是原型链

1. 查找对象的属性的时候现在自身找,如果自身没有沿着__proto__找原型对象
2. 如果原型对象上还没有,继续沿着__proto__,直到找到Object的原型对象对象
3. 如果还没有找到返回undefined
4. 原型链: 沿着__proto__查找的这条链就是原型链

变量提升 & 函数提升

1. js引擎在js代码正式执行之前会做一些预解析的工作
2. 找关键字: var, function
3. 找到var以后将var后边的变量提前声明,但是不赋值 var a;
4. 找到function以后定义对应的函数,也就是说函数在预解析的时候已经定义完毕
5. 预解析: 全局预解析,局部预解析
6. 注意:
    - 全局预解析在定义函数的时候不关心函数是否被使用
    - 函数局部预解析的时候如果内部函数没有被使用就不会提前定义

执行上下文

1. 理解: 
    - 执行上下文抽象的概念,代表了代码执行的环境,包含: 执行环境,变量对象,this,作用域链
2. 流程:
    - js引擎在js代码正式执行之前会先创建一个执行环境(开发商批的地,工程队施工的环境)
    - 进入该环境以后创建一个变量对象(打地基),该对象用于收集当前环境下的: 变量,函数,函数的参数,this
        - 找关键字var ,function
    - 确认this的指向
    - 创建作用域链
3. 重点:
    - 执行上下文是动态创建的
    - 尤其是针对函数,每调用一次函数都会创建一次执行上下文

作用域

作用域理解

  • 抽象的概念
  • 用来决定代码执行的范围, 变量所属的范围
  • 作用域是代码定义的时候决定的
  • 作用域作用:
    • 隔离变量
    • 规定其之后的作用域链是什么样的,体现: [[scopes]]: 上一级作用域链

作用域链

  • 作用域链式一个数组结构
  • 该结构内保存的是一个个的变量对象
  • 作用域链什么时候创建的:在js代码正式执行之前创建的

闭包

闭包形成的条件

  • 函数嵌套
  • 内部函数引用外部函数的局部变量
  • 内部函数被使用,注意: 函数变量提升的时候如果内部函数没有被使用,在预解析的过程中不会定义内部函数

什么是闭包

  • 闭包是一个存在内部函数的引用关系
  • 该引用指向的是外部函数的局部变量对象(前提是内部函数使用了外部函数的局部变量)
 // 1. 将函数作为另一个函数的返回值
  function fn1() {
     
    var a = 2

    function fn2() {
     
      a++
      console.log(a)
    }

    return fn2
  }
  var f = fn1()
  f() // 3
  f() // 4

  // 2. 将函数作为实参传递给另一个函数调用
  function showMsgDelay(msg, time) {
     
    setTimeout(function () {
     
      console.log(msg)
    }, time)
  }
  showMsgDelay('hello', 1000)

闭包的作用

  • 延长外部函数变量对象的生命周期
  • 使用闭包能够间接的从函数外部访问函数内部的私有变量

闭包的优缺点

  • 优点: 延长外部函数变量对象的生命周期
  • 缺点: 延长外部函数变量对象的生命周期(占内存,如果不及时清除容易造成内存溢出,泄漏)

使用闭包的时候注意:

  • 及时清除闭包
  • 让内部的函数成为垃圾对象 —> 内部函数身上没有指针指向

new操作符都干了哪些事情

1. 创建一个空对象
2. 将this指向该空对象
3. 执行函数
4. 将执行的结果返回

你可能感兴趣的:(web前端)