0
点赞
收藏
分享

微信扫一扫

聊聊k8s服务发现的优缺点

星河出山 03-30 15:30 阅读 2

目录

一、作用域

(一)局部作用域

1.函数作用域

2.块作用域

(二)全局作用域

二、垃圾回收机制 GC

(一)生命周期

1.内存分配

2.内存使用

3.内存回收

4.特殊情况——内存泄漏:

注意:

(二)算法说明

1.堆栈空间分配区别

2.常见的浏览器垃圾回收算法

引用计数法(基本不咋用)

标记清除法

三、闭包

(一)闭包简介

(二)闭包的基本格式

(三)闭包应用——实现函数的私有

四、变量提升

五、函数进阶

(一)函数提升

(二)函数参数

1.动态参数

2.剩余参数

 展开运算符

求最大值

合并数组

(三)箭头函数

1.箭头函数介绍

2.基本语法

2.箭头函数参数

2.箭头函数 this

六、解构赋值

(一)数组解构

 特殊情况

1.变量多单元值少

2.变量少单元值多

3.利用剩余参数解决 2

 4.防止 undefined 传递

 5.按需导入忽略某些值

 6.支持多维数组的解构

(二)对象解构(特别重要)

1.对象解构语法

2.对象解构改名

3.简单数组对象解构

4.多级对象解构

遍历数组 forEach 方法 (重点)

筛选函数 filter 方法(重点)

练习: 对象解构在函数中的用处


一、作用域

(一)局部作用域

作用域链的本质是:底层的变量查找机制

函数被执行时,优先查找当前函数作用域,如果找不到再层层往父亲层次查找,直到全局作用域

嵌套关系的作用域串联起来形成了作用域链

而且父亲不能访问孩子

1.函数作用域

函数内部声明的变量,外部无法访问,函数执行完毕内部的变量被清空了

2.块作用域

在 JavaScript 中被 { } 包围的代码被称为代码块,在代码块内部被声明的变量有可能无法被访问

用 let 和 const 声明会产生块作用域,外面无法访问

var 定义的变量不会产生块级作用域,外面可以访问

(二)全局作用域

<script> 标签 和 .js 文件的最外层,就是全局作用域,在其中声明的变量在其他作用域也可被访问

window 对象添加的属性默认也是全局的,不推荐

函数中没用关键字声明的 也默认为全局变量,不推荐

尽量少的减少全局变量,防止污染。

二、垃圾回收机制 GC

js 中内存的分配和回收都是自动完成的,内存在不使用的时候会被垃圾回回收器自动回收

(一)生命周期

js 环境中分配的内存,一般的生命周期:

1.内存分配

声明变量函数对象时,系统自动分配内存

2.内存使用

读写内存,使用变量函数等

3.内存回收

使用完毕,由垃圾回收器自动回收不再使用的内存

4.特殊情况——内存泄漏:

程序中的内存由于某种原因未释放,或无法释放

注意:

全局变量一般不回收,关闭页面时回收

局部变量的值,不用了会被自动回收

(二)算法说明

1.堆栈空间分配区别

1、栈:操作系统自动分配释放函数的参数值,局部变量等,基本数据类型放到栈里面。

2、堆:由程序员分配释放,如果程序员不释放,就由垃圾回收机制回收,复杂数据类型放到堆里面。

2.常见的浏览器垃圾回收算法
引用计数法(基本不咋用)

定义内存不再使用的对象,看对象是否有指向它的引用,如果没有引用了就回收对象。

但是如果两个对象相会被引用 就无法回收了,因为一直使用这两个对象

算法:

记录被引用的次数

被引用就次数加 1 多次就累加

如果减少就减 1 --

引用次数为 0 就释放内存

标记清除法

定义无法到达的对象,从根部定期扫描对象,就是全局变量找不到的对象,就需要被回收。解决了上一个算法的问题

三、闭包

(一)闭包简介

一个函数堆周围状态的引用捆绑在一起,内层函数中访问到其外层函数的作用域

内存函数加外层函数的变量就是闭包,就是里层函数使用外层函数的变量

<body>
  <script>
    function outer() {
      const a = 1
      function f() {
        console.log(a)
      }
      f()
    }
  </script>
</body>

(二)闭包的基本格式

外部的函数调用了函数内部的变量,最后本质是用 fun() 调用了 fn 函数

<body>
  <script>
    function outer() {
      const i = 1
      function fn() {
        console.log(i)
      }
     return fn
    }
    const fun =outer()
    fun()
  </script>
</body>

(三)闭包应用——实现函数的私有

比如统计函数被调用的次数,调用就次数加一

不能使用全局变量 容易被修改 所以可以用闭包进行封装

在外面改变 i 的值不会影响 结果的计算 因为 i 是局部作用域 在外面无法改变

而且 i 局部变量不会被回收 这是很巧妙的地方,外面定义了个全局作用域 result 一直在调用

count(),这样函数不结束被调用就不会被销毁,就能一直加加 i

这也属于内存泄露的一种情况

<body>
  <script>
    function count() {
      let i = 0
      function fn() {
        i++
        console.log(i)
      }
      return fn
    }
    const result = count()
  </script>
</body>

四、变量提升

es6 引入了块级作用域,let const 就更方便了

允许变量被声明前被访问 只有 var 变量存在

在代码执行前,会检测所有 var 变量 然后提到当前作用域的最前面进行定义

下面这段代码不会报错,按理来说会报错的,因为代码按顺寻执行,但是因为 var 变量 变量提升,所以定义了 var 类型的变量 num 但是赋值不会提升,所以输出 undefined

只提升声明 不提升赋值

<body>
  <script>
    console.log(num)
    var num = 10
  </script>
</body>

五、函数进阶

(一)函数提升

代码执行前也会 把所有函数声明提到当前作用域的最前面

<body>
  <script>
   fn()
   function fn(){
    console.log('函数提升')
   }
  </script>
</body>

 只提升函数声明不提升函数调用,调用还是按顺序执行的

下面这种情况会报错注意,因为下面 var 变量提升 但是只提升定义不提升赋值

就相当于

var fn

fn()

fn = function()

fn 被调用时不是个函数,所以会报错

<body>
  <script>
   fn()
   var fn = function (){
    console.log('函数提升')
   }
  </script>
</body>

(二)函数参数

1.动态参数

不知道实参的数量时 就可以用动态参数

arguments 函数内部内置的伪数组变量,包含了调用函数时传入的所有实参

只存在于函数内部,是动态的,实参有几个,伪数组里面就有几个

<body>
  <script>
   function getSum(){
    console.log(arguments)
   }
   getSum(2, 3, 1)
  </script>
</body>

 将 arguments 伪数组里面的元素求和

<body>
  <script>
    function getSum() {
      let sum = 0
      for (let i = 0; i < arguments.length; i++) {
        sum += arguments[i]
      }
      console.log(sum)
    }
    getSum(2, 3, 1)
  </script>
</body>
2.剩余参数

剩余参数也能完成上面的任务,不知道实参的数量,它是个真数组,可以用 push pop 方法

剩余参数允许我们将一个不定数量的参数表示为一个数组,它是把剩余的参数变成一个数组

用法差不多,实际开发中提倡使用 剩余参数

下面的例子中,先把 2 传到 参数 1 然后把 3 传给参数 b 最后把1, 5 ,9 单独封装成一个数

组,剩余参数的名字就是这么来的,就是被剩下的参数

<body>
  <script>
    function getSum(a, b, ...arr) {
      console.log(arr)
    }
    getSum(2, 3, 1, 5, 9)
  </script>
</body>
 展开运算符

... 三个点,如果不用在 函数参数中,就是起到展开数组的作用

最大的用处就是 求数组最大值,合并数组等

<body>
  <script>
    const arr = [1, 2, 3]
    console.log(...arr)
  </script>
</body>
求最大值

...能把数组变成字符串的形式

<body>
  <script>
    const arr = [1, 2, 3]
    console.log(Math.max(...arr))
  </script>
</body>
合并数组
<body>
  <script>
    const arr1 = [1, 2, 3]
    const arr2 = [2, 3, 4]
    const arr = [...arr1, ...arr2]
    console.log(arr)
  </script>
</body>

(三)箭头函数

1.箭头函数介绍

引入箭头函数的目的是让函数书写更简短,而且不绑定 this 箭头函数比函数表达式更简洁,

主要用于本来需要使用匿名函数的地方

2.基本语法

两种函数新旧对比,参数就正常写在小括号中

<body>
  <script>
    // 旧版函数写法
    const fn = function(){
      console.log(123)
    }
    // 新版箭头函数写法
    const fn1 = () => {
      console.log(123)
    }
  </script>
</body>

如果参数参数只有一个,小括号可以省略

<body>
  <script>
    const fn = x => {
      console.log(x)
    }
    fn(1)
  </script>
</body>

只有一行代码时可以省略大括号

<body>
  <script>
    const fn = x => console.log(x)
    fn(1)
  </script>
</body>

箭头函数能直接返回一个对象,因为后面大括号和对象的大括号冲突了,所以用小括号包住

<body>
  <script>
    const fn = (uname) => ({ uname: uname })
    fn('一个人')
  </script>
</body>
2.箭头函数参数

箭头函数没有 arguments 动态参数,但是有剩余参数 ...args

<body>
  <script>
    const getSum = (...arr) => {
      let sum = 0
      for (let i = 0; i < arr.length; i++) {
        sum += arr[i]
      }
      return sum
    }
    console.log(getSum(2, 3))
  </script>
</body>
2.箭头函数 this

函数外面的 this 指向 window 默认是 window

dom 回调函数中还是不推荐使用 箭头函数

this 之前的定义是 this 指向函数的调用者

这里的 this 指向对象 obj

<body>
  <script>
    const obj = {
      uname: '一个人',
      say: function () {
        console.log(this)
      }
    }
    obj.say()
  </script>
</body>

箭头函数的 this 指向箭头函数的上一级作用域链

下面代码都指向 window

<body>
  <script>
    const fn = () => {
      console.log(this)
    }
  </script>
</body>
​

<body>
  <script>
    const obj = {
      uname: '一个人',
      say: function () {
        console.log(this)
      }
    }
    obj.say()
  </script>
</body>

​

六、解构赋值

(一)数组解构

是将数组的单元值快速批量的赋值给一系列变量的简洁语法,就是把数组元素赋给变量,能分别得到三个变量

<body>
  <script>
    const arr = [100, 60, 80]
    const [max, min, avg] = arr
    console.log(max)
  </script>
</body>

 例子如下:数组解构时一定要在数组的前面加上分号,同理立即执行函数,要不然数组前面的数字就会连上数组 ,变成2 [b, a] = [a, b] 从而报错

<body>
  <script>
    let a = 1
    let b = 2;
    [b, a] = [a, b]
    console.log(a, b)  
  </script>
</body>
 特殊情况
1.变量多单元值少

如下代码,变量有a,b,c ,d 四个变量,但是只有1,2,3 三个单元值,abc 分别被赋值123,d的值为 undefined 很像前面的变量的赋值。

<body>
  <script>
   const [a,b,c,d] = [1,2,3]
  </script>
</body>
2.变量少单元值多

多余的单元值就不进行赋值了

3.利用剩余参数解决 2

利用 ... 展开运算符来存其余的数值

<body>
  <script>
   const [a,b,...c]= [1,2,3,4]
  </script>
</body>
 4.防止 undefined 传递

设置一个默认参数就能解决

<body>
  <script>
   const [a = 0,b = 0]= [1,2]
  </script>
</body>
 5.按需导入忽略某些值

如下面例子 就忽略了 后面的值 3

<body>
  <script>
   const [a,b, ,d]= [1,2,3,4]
  </script>
</body>
 6.支持多维数组的解构

下面成功帮助多维数组解构了

<body>
  <script>
   const [a, b, [c,d]] =  [1, 2, [3, 4]]
  </script>
</body>

(二)对象解构(特别重要)

将对象属性和方法快速批量赋值给一系列变量的简洁语法

1.对象解构语法

注意:必须等号左右两边的属性名和变量名必须相同,而且之前不能起和对象内部属性相同的变量名,要不然就会 undefined。

下面的例子和数组结构的方法类似

<body>
  <script>
    const { uname, age } = {
      uname: '一个人',
      age: 18
    }
    console.log(uname)
  </script>
</body>
2.对象解构改名

对象解构的变量名可以改名,但是语法很特殊,新改的名字写在后面。

<body>
  <script>
    const { uname: name, age } = {
      uname: '一个人',
      age: 18
    }
    console.log(name)
  </script>
</body>
3.简单数组对象解构
<body>
  <script>
   const arr = [{
    uname: '一个人',
    age: 18
   }]
   const [{uname, age}] = arr
   console.log(uname)
  </script>
</body>
4.多级对象解构

就如下形式书写即可,数组对象同理

<body>
  <script>
   const pig = {
    name: '佩奇',
    family:{
      mother: '猪妈妈',
      father: '猪爸爸',
      sister: '乔治'
    }
   }
   const {name, family:{mother, father,sister}} = pig
   console.log(mother)
  </script>
</body>

遍历数组 forEach 方法 (重点)

和 map 遍历类似 但是 map 最后返回一个数组 forEach 只进行遍历不返回数组,可以看作加强版的 for 循环

语法:被遍历的数组.forEach(function (当前数组元素,当前元素索引号)){

函数体

}

当前数组元素就是数组里面的值,会依次遍历输出出来,index 是每个元素的下标,下标可以省略

<body>
  <script>
    const arr = ['red', 'green', 'pink']
    const result = arr.forEach(function (item, index) {
      console.log(item)
      console.log(index)
    })
  </script>
</body>

筛选函数 filter 方法(重点)

filter() 方法是创建一个新的数组,新数组中的元素是通过检查指定数组中符合条件的所有元素,用于筛选数组中符合条件的元素,并返回筛选后的数组。

<body>
  <script>
    const arr = [10, 20, 30]
    const newArr = arr.filter(item => item >= 20)
    console.log(newArr)
  </script>
</body>

练习: 对象解构在函数中的用处

结果展示:

 代码部分:
 

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

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>

<body>
  <script>
    const msg = {
      "code": 200,
      "msg": "获取新闻列表成功",
      "data": [
        {
          "id": 1,
          "title": "5G商用自己,三大运营商收入下降",
          "count": 58
        },
        {
          "id": 2,
          "title": "5G商用自己,三大运营商收入下降",
          "count": 56
        },
        {
          "id": 3,
          "title": "5G商用自己,三大运营商收入下降",
          "count": 1669
        }

      ]
    }
    function jie({ data: myData }) {
      console.log(myData)
    }
    jie(msg)
  </script>
</body>

</html>
举报

相关推荐

0 条评论