立即执行函数

    // 1.立即执行函数: 不需要调用,立马能够自己执行的函数
    function fn() {
      console.log(1);
    }
    fn();

    // 2. 写法 也可以传递参数进来
    // 1.(function() {})()    或者  2. (function(){}());
    (function (a, b) {
      console.log(a + b);
      var num = 10;
    })(1, 2); // 第二个小括号可以看做是调用函数

    (function sum(a, b) {
      console.log(a + b);
      var num = 10; // 局部变量
    }(2, 3));

    // 3. 立即执行函数最大的作用就是 独立创建了一个作用域, 
    // 里面所有的变量都是局部变量 不会有命名冲突的情况

    // 4、不会报出匿名函数的语法错误;
    +function () {
      console.log("立即调用的函数")
    }();
    
    //立即执行函数的匿名函数
    // 一般情况下用来:
    // 1、限制作用域
    // 2、处理闭包 
    var lis = document.querySelectorAll("li")
    for (var i = 0; i < lis.length; i++) {
      (function (num) {
        lis[i].onclick = function () {
          // 获取下标
          console.log(num)
        }
      })(i)
    }
    // 每次循环的时候都创建一个活动对象
    // 创建5个活动对象
    // 活动对象里面每个对象都有一个数据,数据分为0、1、2、3、4
    // 形参 === 局部变量
    

深浅克隆

    // 对象的深浅克隆 ; 
    
     var a = 10;
    // 内存存储数据是有机制 : 
    // 1. 栈 : 队列;  先进后出; LIFO; last in first out  
    // 2. 堆 : 树形结构 ( 完美二叉树 ) ;  

    // 栈结构存储数据方式 :  key=value
    // 浅克隆 :  两个变量公用一个地址;

    var a = {}; // a => 0101
    var b = a; // 引用克隆对象的地址;
    console.log(a === b); //true

    var a = {};
    var b = {}; // 创建一个和a一样的新对象
    console.log(a === b); // false

    // 1. 浅克隆 : 对象长得一样,地址也一样;
    // 2. 深克隆 : 对象长得一样, 地址不一样;

    var a = {
      obj: {
        arr: [1, 2, 3, 4, 6],
        key: "value",
        obj: {
          a: 10
        }
      }
    }

    // 看 a 结构 需要创建四个地址;
    // 那怎么创建一个和 a 一样的对象呢???
    
    // 1、 递归 ; 复杂切性能差;
    // IE8 +  的浏览器 ; 
    
    // 2、对象的深克隆 黑科技;
    // JSON.parse(JSON.stringify(对象))
    // 2.1、把对象变成了纯字符串;
    // 2.2、用解析器把字符串重新解析成对象;
    var b = JSON.parse(JSON.stringify(a));
    console.log(b); //一个和a 一样的对象
    console.log(a == b, a.obj == b.obj) //false false

Object.assign() 方法使用

用于将所有可枚举属性的值从一个或多个源对象复制到目标对象。它将返回目标对象。
推荐MDN的Object.assign()

// 第一种使用方式
    const obj = {
      a: 1,
      b: 2,
      c: 3
    }
    const copy = Object.assign({}, obj)
    console.log(copy)  //{a: 1, b: 2, c: 3}


    // 第二种使用方式
    const target = {
      a: 1,
      b: 2
    }
    const source = {
      b: 10,
      c: 20
    }
    const returnTarget = Object.assign(target, source)
    console.log(returnTarget) //{a: 1, b: 10, c: 20}
    console.log(target) //{a: 1, b: 10, c: 20}
    // 注意点:目标对象自身也会改变
    console.log(target === returnTarget) //true

    
    // 第三种 默认值的实例
    function fun(options) {
      options = Object.assign({ a: 1, b: 1 }, options)
      console.log(options)
    }

    fun() //{a: 1, b: 1}
    // 当调用函数 没有传参数时 options为undefined 打印默认值 
    fun({ a: 10, b: 20 })  //{a: 10, b: 20} 
    // 当调用函数传入参数时,合并传入的参数 
    

apply() 冷知识使用方法

apply()调用一个具有给定this值的函数,以及作为一个数组(或类似数组对象)提供的参数。

引用Function.prototype.apply()的使用

func.apply( thisArg, [argsArray] )
thisArg
必选的。在 func 函数运行时使用的 this 值。请注意,this可能不是该方法看到的实际值:如果这个函数处于非严格模式下,则指定为 null 或 undefined 时会自动替换为指向全局对象,原始值会被包装。
——
argsArray
可选的。一个数组或者类数组对象,其中的数组元素将作为单独的参数传给 func 函数。如果该参数的值为 null 或 undefined,则表示不需要传入任何参数。从ECMAScript 5 开始可以使用类数组对象。 浏览器兼容性 请参阅本文底部内容。


    // 第一种用法 :求值
    // 求数组中的最大值和最小值
    const arr = [1, 2, 3, 4, 5, 1, 2, 3, 4, 5]
    const max = Math.max.apply(null, arr)
    //const max = Math.max.apply(false, arr) //注意 这里为false也可以
    console.log(max) // 5
    const min = Math.min.apply(null, arr)
    //const min = Math.min.apply(false, arr) //注意 这里为false也可以
    console.log(min) // 1

    // 第二种用法 :合并数组
    // 用apply将数组添加到另一个数组
    var array = [1, 2, 3]
    var element = ["a", "b", "c"]

    array.push.apply(array, element)
    console.log(array) // [1, 2, 3, "a", "b", "c"]
    console.log(element)  // ["a", "b", "c"]

    element.push.apply(element, array)
    console.log(element) // [1, 2, 3, "a", "b", "c"]
    console.log(array)  // [1, 2, 3]
    // 注意 :array 和 element 两个数组的位置调换会影响结果
    // concat确实具有我们想要的行为,但它实际上并不附加到现有数组,而是创建并返回一个新数组。

    // 第三种:推荐看MDN上解释 这里不多解释
    

call()冷知识使用方法

call()方法使用一个指定的 this 值和单独给出的一个或多个参数来调用一个函数。

引用Function.prototype.call()的使用

注意点:
该方法的语法和作用与 apply() 方法类似,只有一个区别,就是 call() 方法接受的是一个参数列表,而 apply() 方法接受的是一个包含多个参数的数组。

function.call( thisArg, arg1, arg2, … )
thisArg
可选的。在 function 函数运行时使用的 this 值。请注意,this可能不是该方法看到的实际值:如果这个函数处于非严格模式下,则指定为 null 或 undefined 时会自动替换为指向全局对象,原始值会被包装。
arg1, arg2, …
指定的参数列表。

描述:

  • call() 允许为不同的对象分配和调用属于一个对象的函数/方法。
  • call() 提供新的 this 值给当前调用的函数/方法。你可以使用 call 来实现继承:写一个方法,然后让另外一个新的对象来继承它(而不是在新对象中再写一次这个方法)。
    // call 的this 使用
    function Product(name, price) {
      this.name = name;
      this.price = price;
    }

    function Food(name, price) {
      Product.call(this, name, price);
      this.category = 'food';
    }

    console.log(new Food('dumpings', 10).name);  // car
    console.log(new Food('dumpings', 10).price);  // 10

    console.log(new Food('cookie', 5))
    // Food {name: "cookie", price: 5, category: "food"}

   // 其他的使用方法看 MDN 里面解释

Array.prototype.slice.call(伪数组集合)和 Array.from(伪数组集合)

伪数组转数组的方法:Array.prototype.slice.call(伪数组集合)
或者ES6的方法: Array.from(伪数组集合)

举例说明:

<body>
  <ul class="list">
    <li>1</li>
    <li>2</li>
    <li>3</li>
  </ul>
  <script>

    let lis = document.getElementsByTagName("li")
    console.log(lis) // HTMLCollection(3) [li, li, li] 伪数组

    //  1、Array.from(伪数组集合)
    arr1 = Array.from(lis)
    console.log(arr1)  // (3) [li, li, li]  数组

    // 2、 Array.prototype.slice.call(伪数组集合)
    arr2 = Array.prototype.slice.call(lis)
    console.log(arr2)  //(3) [li, li, li]  数组

  </script>
</body>

在这里插入图片描述

js执行机制

在这里插入图片描述

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐