this关键字,var与let,const的区别....

96 阅读7分钟

this 关键字

  • 概念: 每一个函数内部都有一个关键字thisthis 的值, 之和函数的调用有关, 与函数书写无关

  • 一个普通的全局函数, 在正常调用的情况下, this === window

  • 如果将函数放置到对象, 通过对象的语法去获取到并调用, 那么 this === 对象

  • 如果将函数作为 事件处理函数, 那么触发的时候, 内部的 this 指向了 事件源

  • 如果将函数作为定时器执行时的函数, 那么触发的时候, 内部的 this 指向了 全局对象 window

      function fn() {
          console.log(this)   // 这一行不能决定 this 的值, 想要知道他的值是什么, 需要调用函数的时候才能确定
      }
    
      // 1. 普通调用方式
      fn()                    // this === window
    
      // 2. 将函数 fn 赋值给 对象obj的c属性 fn 和 obj.c 是一个引用地址
      var obj = {
          a: 1,
          b: '我是对象的属性B',
          c: fn
      }
      obj.c()                 // this === obj     this 指向了调用者
    
      // 3. 事件的方式触发
      var box = document.getElementById('box')
      box.onclick = fn        // this === box     this 指向了 事件源
    
      // 4. 倒计时器
      setTimeout(fn, 0)       // this === window
      setInterval(fn, 1000)   // this === window
    

改变this的指向

    1. call() 可以帮助我们修改函数的 this 指向;
      • 语法 函数.call(this指向谁, 参数1, 参数2, 参数3...) 第二个位置的参数, 会传递到函数中

          var obj = {
          a: 1,
          b: 2,
          c: '我是对象obj的属性c'
          }
        
          function fn(x, y) {
              console.log(this, x, y)
          }
          fn(100, 200)
        
        
          //{a: 1, b: 2, c: '我是对象obj的属性c'} 300 400
          fn.call(obj, 300, 400)
        
    1. apply() 可以帮助我们修改函数的 this 指向;
      • 语法 函数.apply(this指向谁, [参数1, 参数2, 参数3]),第二个位置的数组内数据, 会传递到函数内部

          //{a: 1, b: 2, c: '我是对象obj的属性c'} 500 600
          fn.apply(obj, [500, 600])
        
    1. bind() 可以帮助我们修改函数的 this 指向;
      • 语法 函数.bind(this指向谁, 参数1, 参数2, 参数3...),第二个位置的参数开始, 会传递到函数中

      • 注意: bind 方法不会立即执行函数, 他会返回一个 内部 this 修改完毕的 新函数

          // {a: 1, b: 2, c: '我是对象obj的属性c'} 700 800
          var newFn = fn.bind(obj, 700, 800)
          newFn()
        

ES6

  • 1.其实就是 JS 发展过程中的某一个版本而已那个版本的版本号叫做 ES6
  • JS 在最初的时候, 是只有 var 关键可以声明变量 随着版本的更新, 在某一个版本内推出了 新的变量声明方式
  • JS 的更新 在 推出ES6 的时候, 这个版本推出的新东西比较多 所以后续程序员们为了方便记忆, 把ES6以后的版本 统称为 ES6+

let/const 与 var 的差异

    1. let/const 声明的变量 不允许出现重复的
      • 使用 var 声明变量的时候可以出现重复声明, 后一个值会覆盖前一个值
      • let/const 不允许
    1. let/const 声明的变量没有变量提升
      • var 关键字声明的变量有变量提升, 值为 undefined
      • let/const 不允许
    1. let/const 声明的变量 会受限于 所有的 {}
      • 也就是 使用 let/const 声明的变量 是块级作用域
      • var 声明的变量 只受限于 函数内部

let 与 const 的差异

    1. let 声明的叫做变量(后续可以修改内部的值);
      • const 声明的叫做常量(后续不能修改内部的值, 也不能修改内部的引用地址)
    1. 因为 let 后续可以修改变量的值, 所以他首次定义时, 可以不赋值;
      • 但是 const 声明的时常量, 后续不能重新修改他的值, 所以首次定义时, 必须赋值

箭头函数

  • 就是对 ES5 普通函数的 写法上的一个优化
  • 普通写法: (书写形参) => {书写函数调用时执行的代码}
  • 箭头函数的优化
    • 箭头函数如果只有一个形参的时候, 可以不写前边的小括号(除此之外, 必写)

        const fn = a => {
            console.log(a)
        }
      
    • 如果箭头函数的函数体, 只有一行代码, 那么可以省略 大括号(并且会默认将这行代码 return)

        const fn1 = (a, b) => a + b
        let sum = fn1(100, 200)
        console.log(sum)
      

解构赋值

  • 快速从数组或对象中取出成员的一种语法

    • ES6 解构赋值, 解构数组时, 赋值号左边必须写 中括号, 代表数组的解构赋值

        var arr = [1,2,3]
        let [num1, num2, num3] = arr
        console.log(num1, num2, num3)
      
  • ES6 解构赋值, 解构对象时, 赋值号左边 必须写大括 号, 代表对象的解构赋值

    • 大括号内部必须书写对象的 key

        var obj = {
            a: 11,
            b: 21,
            c: 31
        }
        let { a, b, c } = obj
        console.log(a, b, c)
      

箭头函数与普通函数的区别

  • 箭头函数内部没有 this; 所以他的 this 取决于 书写的时候
  • 箭头函数内部没有 arguments 对象

展开(扩展)运算符

  • 语法: ...数组(对象)

  • 作用: 展开数组或者对象,相当于把数组两侧包裹的中括号去掉

    var arr = [1, 2, 3]
    console.log(arr)
    console.log(...arr)
    

Set

  • set 类似于 数组的 一种数据结构

    • 内部按照索引排序(但是不能通过索引取值)
    • 语法 let s = new Set([数据1, 数据2, 数据3])
    • 特点: 天生不支持重复数据
    1. size (类似数组的 length); 作用: 获取到当前数据结构中 数据的数量

       let s = new Set([3, 4, 5, 5, 5, 4, 4, 3])
       console.log(s.size)
      
    1. add 方法; 作用: 向当前数据结构中 新增数据

       s.add(100)
       console.log(s)      //{3, 4, 5, 100}
      
    1. has() 作用: 查询当前数据结构中是否拥有该数据; 找到的时候, 返回 true, 否则返回false

       console.log(s.has(100))     //true
      
    1. delete(数据) 作用: 将当前数据结构中的 这个数据删掉

      s.delete()
       
      
    1. clear() 作用: 清空当前数据结构

      s.clear()
      
    1. forEach 作用: 遍历数据结构, 拿到数据结构的每一项

       s.forEach(function (item, key, origin) {
           // set 数据结构是没有 key 所以 item 和 key 打印出来的值都一样
           console.log(item, key, origin)
       })
      

Map

  • 类似于对象的一种数据结构但是map的key可以是任意类型的值

    • 语法: var m = new Map([key, value])

    • 在实际开发中, 我们使用 map 的场景一般为 想要将对象的 key 用于字符串之外的数据时使用

        var arr = [1, 2, 3]
        var arr1 = [4, 5, 6]
        var m = new Map([[[500], [600]], [arr, arr1], ['arr123', arr1]])
      
    1. size 作用: 返回当前数据结构的 数据长度(多少个)

       console.log(m.size)
      
    1. set() 作用: 向当前数据结构中, 新增数据

       m.set('newKey', [1, 2, 3, 4, 5])
       
      
    1. get(key) 作用: 获取到指定key 对应的 value

       console.log(m.get(arr))
       console.log(m.get('newKey'))
      
    1. has(key) 作用: 查询数据结构中是否存在当前 key; 存在返回一个 true ,否则返回一个 false

      console.log(m.has('12345'))
       console.log(m.has('newKey'))
      
    1. delete 作用: 删除当前数据结构对应的 key

       m.delete('newKey')
      
    1. clear 作用: 清空当前数据结构

       m.clear()
       
      
    1. forEach

       m.forEach(function (item, key, origin) {
           // item: 对应的 value,key: 对应的 key,origin: 对应的原始数据结构
           console.log(item, key, origin)
       })
      

对象语法的简写

    1. key 和 value 拼写一样
    1. 并且 value 写的是一个变量
      • 满足这两个条件的情况, 可以少写 其中一个

模块化开发

  • 就是将功能拆分开, 每一个功能写到一个 JS 文件中 (整理出来 积木 一个个的模块)

    • 后续根据实际需求, 将不同的 JS 文件拼接到一起
    • 将多个逻辑分别写道多个JS文件中
    • 每一个文件, 都只能使用当前文件内的变量
    • 每一个文件, 就是一个独立的作用域(文件作用域)
  • ES6 使用 模块化开发的前提

    • 页面必须使用 服务器的形式打开
    • script 标签行内 必须配置 type="module"
  • 如果想要拼接的话, 需要导入别的文件到自己文件内

    • 前提: 导入的文件, 必须有导出的内容
    • 导出: 向外部暴露出一些内容, 可以是变量, 也可以是函数
    • 导入: 引入别的文件向外部暴露出的那些内容