最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • 整理Javascript知识

    正文概述 掘金(Nothing)   2021-01-21   393

    闭包:

    概念:函数执行后返回结果是一个内部函数, 并被外部变量所引用,如果内部函数持有被执行函数的作用域变量,形成了闭包。

    可以在内部函数访问到外部函数作用域。使用闭包,一可以读取函数中的变量,二可以将函数中的变量存储在内存中,保护变量不被污染。正是因闭包可以把函数中的变量存储在内存中,会对内存有消耗,所以不能滥用闭包,否则会造成内存泄露。

    防抖

    概念: 在事件被触发n秒后再执行回调,如果在这n秒内又被触发,则重新计时!

    场景: 防止按钮多次提交,只执行最后一次;搜索框-防止输入重复发请求。

    function fun(a) {
      console.log(a, 'btn click!')
    }
    function debounce(callback, wait) {
      let timer;
      return function () {
        const that = this, args = arguments;
        clearInterval(timer);
        timer = setTimeout(() => {
          callback.apply(that, args);
        }, wait);
      }
    }
    
    const btn = document.getElementById('btn');
    
    btn.onclick = debounce(() => { fun('8888') }, 1000);
    

    节流

    概念:规定在一个单位时间内,只能触发一次函数。如果这个单位时间内触发多次函数,只有一次生效。

    场景: 拖拽;缩放场景。

    实现方案: 时间戳和定时器实现。

     时间戳
    function throttle(callback, time) {
      let pre = 0;
      let that, agrs;
      return function () {
        that = this; agrs = arguments;
        let now = +new Date();
        if (now - pre > time) {
          callback.apply(that, agrs);
          pre = now;
        }
      }
    }
    定时器
    function throttles(callback, time) {
      let timer = null;
      return function () {
        const that = this; const agrs = arguments;
        timer = setInterval(() => {
          callback.apply(that, agrs)
          timer = null;
        }, time);
      }
    }
    const btn = document.getElementById('btn');
    
    btn.onclick = throttles(() => { fun('9999') }, 1000);
    

    浅拷贝&&深拷贝

    浅拷贝:是创建一个新对象,这个对象有着原始对象属性值的一份精确拷贝, 如果其中一个对象改变了这个地址,就会影响到另一个对象。

    深拷贝:是将一个对象从内存中完整的拷贝一份出来,从堆内存中开辟一个新的区域存放新对象,且修改新对象不会影响原对象。

    区别:主要区别是其在内存中的存储类型不同,栈为自动分配的内存空间,它由系统自动释放;而堆则是动态分配的内存,大小不定也不会自动释放。[基本数据类型存放在栈中,引用类型存放在堆中]。

    举个?

    let k = {
      a: 1,
      b: 2,
      c: 3,
      d: {
        e: 4,
      },
      f: {
        g: 5,
      }
    };
    let h = JSON.parse(JSON.stringify(k)); // 深复制包含子对象- 深拷贝
    let l = { ...k }; // 拷贝一层但不包含子对象 // 浅拷贝 
    let o = k; // 赋值
    解析: 
     o.b = 22; // k、o 相同: { a: 1, b: 22, c:3, d: {e: 5}, f: {g: 6} }
     l.c = 33; // k: 不变; l: { a: 1, b: 22, c:33, d: {e: 5}, f: {g: 6} }
     l.d.e = 55; // k、l 相同: { a: 1, b: 2, c:3, d: {e: 55}, f: {g: 6} }
     h.f.g = 66; // k:不变; h: { a: 1, b: 2, c:3, d: {e: 5}, f: {g: 66} }
    

    结论:
    整理Javascript知识

    浅拷贝方法

    • es6-解构;
    • Object.assign();
    • lodash-_.clone;
    • Array.prototype-[concat()|slice()].

    深拷贝方法

    • JSON.parse(JSON.stringify());
    • lodash-_.cloneDeep;
    • 递归拷贝所有层级属性.

    数组

    • 数组去重
      const arr = [1, 2, 3, 4, 5, 3, 2, 5, 5, 4, 3, 6];
      
      1.定义一个新数组,for 循环原数组,判断结果数组是否存在当前元素,如果有相同的值则跳过,不相同则push进数组.
      function repeat1(arr) {
        let newArr = [];
        for (let i = 0; i < arr.length; i++) { // forEach / filter
          if (newArr.indexOf(arr[i]) === -1) { // !newArr.includes(arr[i])
            newArr.push(arr[i]);
          }
        }
        return newArr;
      }
      
      2.先将原数组排序,再与相邻的进行比较,如果不同放入新数组.
      function repeat2(arr) {
        let as = arr.sort();
        let newArr = [arr[0]];
        for (let i = 1; i < arr.length; i++) {
          if (as[i] !== as[i - 1]) {
            newArr.push(as[i]);
          }
        }
        return newArr;
      }
      
      3.使用es6 Set.
      function repeat3(arr) {
        return [...new Set(arr)];
      }
      
      4.与相邻的进行比较,截取相同的元素.
      function repeat4(arr) { // 会改变原数组
        for (let i = 0; i < arr.length; i++) {
          for (let j = i + 1; j < arr.length; j++) {
            if (arr[i] === arr[j]) {
              arr.splice(j, 1);
              j--;
            }
          }
        }
        return arr;
      }
      
    
    • 数组排序

    冒泡排序:比较每相邻的两个数,若前者大于后者,把两个数进行位置交换;第一轮可以选出最大的数放在后面,经过n-1轮,完成每个数的排序。

    const sort = [1, 2, 10, 8, 3, 6, 7, 5];
    function arrSort(arrs) {
      for (let i = 0; i < arrs.length - 1; i++) {
        for (let j = 0; j < arrs.length - i - 1; j++) {
          if (arrs[j] > arrs[j + 1]) {
            const temp = arrs[j];
            arrs[j] = arrs[j + 1];
            arrs[j + 1] = temp;
          }
        }
      }
      return arrs;
    }
    console.log(arrSort(sort)); // [1, 2, 3, 5, 6, 7, 8, 10]
    

    插入排序:获取当前索引元素, 从右向左搜索放到数组正确位置。

    function insertionSort(arr) {
      let preIndex, current;
      for (let i = 1; i < arr.length; i++) {
        preIndex = i - 1; current = arr[i];
        while (preIndex >= 0 && arr[preIndex] > current) {
          arr[preIndex + 1] = arr[preIndex];
          preIndex--;
        }
        arr[preIndex + 1] = current;
      }
      return arr;
    }
    console.log(insertionSort(sort)); // [1, 2, 3, 5, 6, 7, 8, 10]
    

    快速排序:找到数组的中间数, 并创建两个空数组left&right; 然后遍历数组,数组里每一项与中间数比较,小于中间数放在left,大于中间数放在right, 最后将left和right递归调用拼接完整的数组。

    function fastSort(sort) {
      const arr = JSON.parse(JSON.stringify(sort));
      if (arr.length <= 1) return arr;
      const index = Math.floor(arr.length / 2);
      const temp = arr.splice(index, 1);
      let left = [], right = [];
      for (let i = 0; i < arr.length; i++) {
        if (arr[i] < temp[0]) {
          left.push(arr[i]);
        } else {
          right.push(arr[i]);
        }
      }
      return fastSort(left).concat(temp, fastSort(right));
    }
    console.log(fastSort(sort)) // [1, 2, 3, 5, 6, 7, 8, 10]
    

    执行结果

    • 执行函数
    function side(arr) {
      arr[0] = arr[2];
      return arr;
    }
    function a(a, b, c = 3) {
      c = 10;
      console.log('arguments', arguments)
      side(arguments);
      return a + b + c;
    }
    
    const result = a(1, 1, 1);
    console.log(result);  // 12
    
    • 获取 arguments 值
    function getArguments() {
      const args = new Array(arguments.length); // 创建 Array 对象
      console.log('args', args);
      for (let i = 0; i < args.length; i++) {
        args[i] = arguments[i];
      }
      return args;
    }
    
    getArguments(1, 2, 3); // [1, 2, 3]
    
    • 比较大小值
    var min = Math.min(), max = Math.max();
    console.log(min < max);
    解析:Math.min 的参数是 0 个或者多个,如果多个参数很容易理解,返回参数中最小的。如果没有参数,则返回 Infinity,无穷大; 而 Math.max 没有传递参数时返回的是-Infinity.所以输出 false。
    
    • 立即执行的函数
    var a = 1;
    (function a() {
      a = 2;
      console.log(a);
    })();
    解析:立即执行的函数表达式(IIFE)的函数名称跟内部变量名称重名后,函数名称优先,因为函数名称是不可改变的,内部会静默失败,在严格模式下会报错。
    
    • 隐式类型转化
    var b = [0]; // "0"
    if (b) {
      console.log(b === true);
    } else {
      console.log(b)
    }
    解析:数组从非 primitive 转为 primitive 的时候会先隐式调用 join 变成“0”,string 和 boolean 比较的时候,两个都先转为 number 类型再比较,最后就是 0==1 的比较了
    
    • delete使用原则
    var company = {
      address: 'beijing'
    }
    var yideng = Object.create(company);
    delete yideng.address
    console.log(yideng.address); // beijing
    解析:delete 操作符用来删除一个对象的属性。
    
    • 函数表达式
    var foo = function bar() { return 12; };
    // console.log(typeof bar());  // bar is not defined
    解析:这种命名函数表达式函数只能在函数体内有效
    
    • typeof
    var x = 1;
    if (function f() { }) {
      //  alert(typeof f) // undefind
      x += typeof f;
    }
    console.log(x);
    
    • var | let
    for (let i = 0; i < 3; i++) {
      setTimeout(() => {
        // console.log(i)
      }, 1);
    }
    // 0 1 2
    
    for (var j = 0; j < 3; j++) {
      setTimeout(() => {
        // console.log(j)
      }, 1);
    }
    // 3 3 3
    
    • this指向
    const num = {
      a: 10,
      add() {
        return this.a + 2;
      },
      reduce: () => this.a -2
    };
    console.log(num.add());  // 12
    console.log(num.reduce()); // NaN
    解析:对于箭头函数,this关键字指向是它所在上下文(定义时的位置)的环境,与普通函数不同! 这意味着当我们调用reduce时,它不是指向num对象,而是指其定义时的环境(window)。没有值a属性,返回undefined。
    
    • call | bind
    const person = { name: "yideng" };
    function sayHi(age) {
      return `${this.name} is ${age}`;
    }
    console.log(sayHi.call(person, 5));
    console.log(sayHi.bind(person, 5));
    解析:使用两者,我们可以传递我们想要this关键字引用的对象。 但是,.call方法会立即执行!.bind方法会返回函数的拷贝值,但带有绑定的上下文! 它不会立即执行。
    

    Git 相关

    • git cherry pick:将指定的提交(commit)应用于其他分支,当只需要部分代码变动(某几个提交),可以使用 git cherry pick。

      例如: 在Master上创建功能分支, 在功能分支上提交的 "feature2",应用到Master上。

         git checkout Master -> git cherry pick "feature2" 
    

    起源地下载网 » 整理Javascript知识

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元