Web前端105天-day-41-JSCORE

JSCORE01

目录

前言

一、声明提升

二、宿主 window

三、断点功能

四、匿名函数解决全局污染

五、作用域链

六、闭包

七、私有

八、arguments

九、函数重载

十、方括号属性语法

十一、重载练习

十二、this

总结


前言

JSCORE01学习开始


一、声明提升

  • 报错方案: 让用户自己修正代码 -- 一定是精确表达用户思想的代码, 但是 麻烦
  • 自动修正: 系统帮用户修正 -- 让程序员舒服 但是 有可能自动修正修错了
  • 修正法案: 声明提升法案

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>声明操作 09:37</title>
</head>

<body>
  <!-- 
    声明: 在内存中开辟一个空间, 起个名字 用于 存放东西, 以后就可以通过这个名字来找到这个东西
    主要分两大类:
    - 变量: 一些固定存在的值
    - 函数: 可以运行的值, 用()触发运行
   -->
  <script>
    // 声明变量 同时 赋值
    var a = 5
    var b = 10
    var c = true

    // 声明函数 同时 赋值
    function show() { }

    function talk() { }

    //
    // 面试考点: JS引擎 与 其他编程语言 不同的地方
    // 声明提升: 
    // -- 初衷: JS引擎会 `智能化` 的把不合理的代码 修正为 合理的代码

    // 不合理: 数学运算表达式中, 参与运算的值 必然是数字类型, 才合理
    // 对于不合理的代码, 有两种方案
    // 1. 报错: C Java  - 强类型语言
    // 2. 自动修正: PHP JS - 弱类型语言; JS引擎会先阅读代码, 把不合理的进行修正, 然后再执行

    console.log(10 + true)
    // 修改为: console.log(10 + 1)  再运行;  隐式类型转换

    // 修正法案: 变量必须先声明 后使用
    // 所以: JS引擎会自动把所有的声明操作提升到 作用域的顶部

    function x() {
      // clg : 可以快速生成console.log
      console.log(111);
    }
    x() //222

    function x() {
      console.log(222);
    }
    x() //222
  </script>
</body>

</html>

二、宿主 window

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>window 10:22</title>
</head>

<body>
  <!-- 
    宿主环境: 寄生的宿主
    JS语言主要有两个宿主环境
    - Node.js: 提供了一套操作服务器的API -- 技能
    - 浏览器: 提供了一套操作浏览器的API -- 技能

    API: 应用程序接口 -- 操作软件的一些 代码
   -->
  <script>
    // 按ESC 退出自动生成后的状态, 写代码才有提示
    console.log(window) //clg

    // window: 称为 全局对象, 其中存放了能够全局使用的`技能`
    // window.alert('你好, window')

    // 设定: 使用变量 或 函数时, 如果没有声明过此变量, 则自动从window中查找使用
    // alert('hello world!')

    // 全局变量污染
    // 系统提供的技能都存放在 window 对象里
    // 可以认为: window对象就是专门存放系统技能的
    // var: 在哪个作用域中书写, 就会在哪个作用域中声明变量
    // --- 直接在脚本中书写, 则存储在window对象里, 造成污染(自定义的值 和 官方给的值都放在一起, 就是污染)
    var a = 10

    // 变量b 没有用var 声明, 则触发另一个场景:
    // 自动从window中查找, b是通过对象的属性新增语法添加的
    b = 20 // window.b = 20
  </script>
</body>

</html>

三、断点功能

四、匿名函数解决全局污染

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>函数作用域 10:43</title>
</head>

<body>
  <!-- 
    与 全局作用域 相对相应的 局部作用域(函数作用域) 
   -->
  <script>
    // 创造函数作用域 -- 提供了一个最快捷的语法 : 匿名函数自调用
    // function x() { }  
    // x()

    // var x = function () { }
    // x()

    // x直接换成函数, 用()包围, 识别为一个整体
    // 实际书写JS时, 为了规避全局污染, 会选择 在脚本中先书写一个匿名函数自调
    // 然后把代码在这里书写即可
    (function () {
      var a = 10
      // 需要利用 浏览器提供的 断点调试 工具, 才能直观看到局部作用域
      console.log(1)

      // var: 在当前作用域中, 声明变量
      // -- 误区: var 就一定全局污染---错误;  在脚本中声明才会

      // 如果找不到声明的b变量, 则从 window 中查找
      b = 20   // window.b = 20

      // 修正法案-- 声明提升法案
      // 声明操作 都会提升到作用域的顶部, 然后才会真正运行
      // var b 就在局部作用域中, b=20 就会赋值给这个b变量, 不会污染
      // var b
    })()

    console.log(window)
  </script>
</body>

</html>

五、作用域链

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>作用域链 11:23</title>
</head>

<body>
  <!-- 
    作用域链: 当出现多层作用域嵌套的场景, 如果使用1个变量时, 按照就近原则查找使用
  -->
  <script>
    var x = 10

    function a() {
      function b() {
        var x = 20
        function c() {
          function d() {
            console.log(x)
          }
          d()
        }
        c()
      }
      b()
    }
    a()
  </script>
</body>

</html>

六、闭包

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>闭包 11:33</title>
</head>

<body>
  <!-- 
    闭包closure : 闭合的,封闭的 包围,包裹

    闭包: 形容的是函数作用域的一种状态 -- 被保存在其他函数的scopes 里, 绑定
    原因: 防止释放
   
    缺点: 费内存, 本来应该释放的函数作用域 无法释放; 永远占据内存 直到被销毁为止
   -->
  <script>
    // 函数作用域: 是 函数 `运行时`  `临时` 生成的作用域

    // 临时: 函数执行完毕后, 其作用域会从内存中释放, 来节省内存
    function y() {
      var b = 20
      var c = 30
      var d = 40
      // 理论上: 函数运行完毕后, 就会自动释放 来 节省内存
      // 但是: 下方的z函数中使用了 y 函数生成的 b 和 c 变量
      // z函数为了确保自身能够正常运行, 把 y函数作用域 保存在自身
      // -- 目标: 防止自身依赖的内容 `跑路`
      // -- 反例: 亮亮办了游泳卡, 结果游泳馆关门了
      var z = function () {
        console.log(b, c);
      }
      // log: 输出 美化后的结果, 函数会直接打印函数字符串
      // dir: direct直接  输出原始对象, 才能看到函数的本体
      console.dir(z)

      // scopes: 作用域们, 数组类型
      // 用于存放函数体中 使用到的 来自其他作用域的变量 所在的作用域

      // 为了区分作用域的类型: 有两个标记词
      // Global: 代表全局作用域, 即window对象
      // Closure: 闭包; 代表函数作用域
      // -- 此称呼代表了函数作用域的一种状态 : 被其他函数绑定了
      // -- 为了节省内存: 只保留有用的变量

      return z
    }

    var z = y() //开内存, 生成b和c变量存放在这里,  执行完就销毁
    z()



    // y() //开内存, 生成b和c变量存放在这里,  执行完就销毁
    // y() //开内存, 生成b和c变量存放在这里,  执行完就销毁
    // y() //开内存, 生成b和c变量存放在这里,  执行完就销毁





    // 函数有两种状态: 静态 和 动态
    function show() { }  //静态: 声明完毕; 买车后停在车库

    show() //动态: 触发后;  开车


    /
    // 面试题
    var a = 10
    function x() {
      a = 20
    }
    // 函数不调用, 则其中代码不会运行
    // x()

    console.log(a)
  </script>
</body>

</html>

七、私有

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>私有变量 14:01</title>
</head>

<body>
  <!-- 私有: 私人拥有, 变量只属于函数自身 -->
  <script>
    // 案例: 制作一个变量, 来记录 x 函数调用的次数
    // 做法1(错误): 在函数中声明变量x, 导致每次运行函数 x 都会初始
    // 做法2(错误): 在函数外声明变量x, 导致同作用域下的其他函数也能修改这个x
    // 做法3(正确): 把x在独立的匿名函数作用域中声明, 实现私有; 再利用闭包机制把x 绑定给函数使用 

    // 匿名函数自调: 为了快速生成函数作用域, 局部作用域
    var x = (function () {
      var n = 0 //专属于 匿名函数作用域的

      // 函数中的n 属于匿名函数作用域, 所以会捆绑存储在 scopes 属性里
      // var x = function(){}
      // return x
      return function () {
        n++
        console.log('调用次数:', n);
      }
      // console.dir(x)

      // return x //利用返回值, 暴露给外部
    })()

    // var n = 0

    // function x() {
    //   n++
    //   console.log('调用次数:', n);
    // }

    x()
    x()
    x()
    x()

    // 练习:
    // 插件 tabout, 用tab键把光标移到括号外
    var y = (function () {
      // 私有变量: 属于匿名函数作用域
      var n = 0
      // 利用闭包机制, 把匿名函数作用域 捆绑在函数上, 保存在其 scopes 属性里
      // 利用return 暴露给外部使用
      return function () {
        n++
        console.log(n)
      }
    })()


    y()
    y()
    y()
    y()
  </script>
</body>

</html>

八、arguments

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>arguments 14:42</title>
</head>

<body>
  <!-- arguments: 是函数中隐式自带的关键词, 其中存储函数收到的所有实参 -->
  <script>
    // uname: 称为形参 -- 应该 见名知意
    function show(uname) {
      // 形参和实参 出现 个数不对应的场景 很常见
      console.log(arguments);
    }

    // 实参 -- 函数真正收到的值
    show('亮亮', 35, '18784556898', true)

    /
    // 用途: 制作实参个数不固定的函数
    var m = Math.max(12, 3, 4, 6, 7)
    console.log(m)

    var m = Math.max(12, 3, 4, 6, 7, 34, 456, 56, 76, 87)
    console.log(m)

    var m = Math.max(12, 3, 4, 6, 7, 43, 2)
    console.log(m)

     制作
    function max() {
      console.log(arguments)
      var x = arguments[0]
      for (var i = 1; i < arguments.length; i++) {
        var value = arguments[i]
        // 语法糖: 作者提供了一些简化语法, 当满足一些固定条件后可以使用
        // 简化 -> 懒: 偷懒可以让人幸福!!  像吃糖一样
        // 如果if的条件只有一行代码, {} 可以省略
        if (value > x) x = value
      }
      return x  //返回最终结果
    }

    // 编程思维: 把人类解决问题的思维 用 代码方式表达出来, 让计算机执行

    console.log(max(12, 33, 54, 65, 765))
    console.log(max(12, 33, 54, 65, 765, 4, 345, 456, 756))
  </script>
</body>

</html>

九、函数重载

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>函数的重载 15:26</title>
</head>

<body>
  <!-- 
    函数重载: 函数内部 根据 实参的 个数 或 类型 不同, 载入不同的逻辑代码
    -- 用于制作 多功能函数,  让一个函数身兼多职
   -->
  <script>
    // 双11 要做一个计算商品折扣信息的函数
    function zheKou(money) {
      console.log(arguments);
      // 3个参数
      if (arguments.length == 3) {
        var man = arguments[1]
        var jian = arguments[2]
        if (money >= man) money -= jian
        console.log('满减实付:', money);
      }

      if (arguments.length == 2) {
        if (typeof arguments[1] == 'number') {
          money *= arguments[1]
          console.log('折扣实付:', money);
        }
        // vip的
        if (typeof arguments[1] == 'string') {
          // if (arguments[1] == 'vip1') money *= 0.9
          // if (arguments[1] == 'vip2') money *= 0.8
          // if (arguments[1] == 'vip3') money *= 0.7
          var list = { vip1: 0.9, vip2: 0.8, vip3: 0.7 }
          // vip_n 中存放的是属性名
          var vip_n = arguments[1]
          money *= list[vip_n]  //通过属性名, 找到要乘的数字

          console.log('vip:', money);
        }
      }
    }

    // 使用有多种用法
    zheKou(5000, 0.7) // 7折优惠
    zheKou(5000, 0.5) // 5折

    zheKou(5000, 3000, 600) //满3000 减600
    zheKou(5000, 4000, 800) //满4000 减800

    zheKou(5000, 'vip1') // 9折
    zheKou(5000, 'vip2') // 8折
    zheKou(5000, 'vip3') // 7折
  </script>
</body>

</html>

十、方括号属性语法

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>属性 15:51</title>
</head>

<body>
  <script>
    // 对象的属性名语法分两种: 点语法   方括号语法
    var emp = { uname: "亮亮", age: 19 }
    // 点语法适合直接书写属性名
    console.log(emp.uname, emp.age)
    emp.phone = '10086'
    console.log(emp);

    // 方括号语法: 适合值是变量的场景 -- 在封装函数时才常见
    var x = 'ename', y = 'age'

    var emp1 = {
      // 当编辑器看到[] 就会识别其中的代码是 JS代码
      [x]: '泡泡',
      [y]: '18',
      [2 + 6]: '999',
      ['ni' + '好']: "哈哈"
    }
    console.log(emp1);

    var z = 'ni好'
    console.log(emp1[z]);
    console.log(emp1.z)// 属性名是 z 的属性
  </script>
</body>

</html>

十一、重载练习

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>练习 16:23</title>
</head>

<body>
  <!-- 
    函数重载: 就是利用实参的 个数 或 类型 不同, 执行不同的逻辑操作
    -- if 结合 arguments 进行判断
    -- 实现多功能函数
   -->

  <script>
    // 累加案例
    var x = 0
    for (var i = 1; i <= 100; i++) {
      x += i
    }

    function sum() {
      var x = 0

      if (arguments.length == 1) {
        for (var i = 1; i <= arguments[0]; i++) {
          x += i
        }
      }

      if (arguments.length == 2) {
        for (var i = arguments[0]; i <= arguments[1]; i++) {
          x += i
        }
      }

      if (arguments.length == 3) {
        for (var i = arguments[0]; i <= arguments[1]; i += arguments[2]) {
          x += i
        }
      }

      console.log(x)
    }

    // 目标效果: 制作一个函数, 能够得到 数字累加的和
    sum(100) // 得到 1 + 2 + 3 + .... + 100 
    sum(200) // 1 + .. + 200

    sum(50, 200) // 得到 50 + 51 + ... + 200 
    sum(11, 44) // 11 + .. + 44

    sum(100, 200, 10)  //得到 100 + 110 + 120 + ... + 200 
  </script>
</body>

</html>

十二、this

  • 方式1: 函数是固定的, 值作为实参 依次传入到函数中, 执行

  • 方式2:上门服务 --函数 直接进入到 值的内部执行

 

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>this 16:50</title>
</head>

<body>
  <!-- 
    this: 这个 -- 到底代表什么, 要看语境
    
    函数拥有此关键词以后, 就提供了另一种用法
    -- 把函数放到对象里执行
   -->
  <script>
    // 保存了矩形的宽和高
    var r1 = { width: 100, height: 50 }
    var r2 = { width: 1, height: 4 }

    function area2() {
      // this: 这个 -- 代表函数运行时所在的对象
      console.log('this:', this);
      return this.width * this.height
    }

    r2.area2 = area2
    var y = r2.area2()
    console.log(y)

    // 函数上门服务
    r1.area2 = area2 // 存放到r1对象里
    var x = r1.area2() // 通过 r1 对象来触发 -- 激活
    console.log(x)






    // 算面积
    function area(r) {
      return r.width * r.height
    }
    // 把值传入函数中, 进行处理
    console.log(area(r1))
  </script>

</body>

</html>


总结

  • 声明提升
    • JS引擎的智能化法案 -- 内部有一套规则, 会把不规范的代码 自动修改为规范的代码, 然后执行(最好的方案: 不要书写不规范的代码 )
    • 不规范: 表达式中参与运算的值, 类型不正确, 就会自动类型转换(什么类型 在什么场景 会 应用哪种转换规则 -- 需要记忆
    • 声明操作
    • 规范要求: 必须先声明, 后使用
    • 一旦你的代码不规范, 则会触发隐形的声明提升操作, 把 所有声明操作 提升到 代码的顶部
  • 宿主环境: JS运行在什么环境下, 就能使用此环境中的api - 技能
    • node.js: 处理服务器相关的api
    • 浏览器: 处理浏览器有关的, 存放在 window 的对象里
  • 作用域
    • 全局:
    • 局部: 函数执行时临时生成的
  • 规避全局污染:
    • 利用 匿名函数自调用 生成函数作用域, 在这个作用域中声明变量 就不会污染全局
  • 闭包:
    • 函数中使用来自其他函数中的变量, 为了防止其释放 而导致自身无法使用
    • 所以: 保存在自身的 scopes 属性里 -- 绑定
    • 这种被绑架 的函数作用域, 就处于 闭包状态
  • 私有化:
    • 利用闭包特性, 来获取私有的作用域变量
  • 作用域链:
    • 函数中使用变量, 会从距离最近的作用域中查找使用
  • arguments:
    • 函数中隐式带有的属性, 保存了所有实参
    • 制作实参个数不固定的函数 -- 求最大值
    • 函数重载: 多功能函数
  • this:
    • 这个; 代表函数运行时所在对象
    • 此关键词就赋予了函数 进入到 对象中运行的能力
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值