zoukankan      html  css  js  c++  java
  • JavaScript 核心原理精讲

    JS数据类型

      基础类型:undefinedNullBooleanStringNumberSymbolBigInt。(存储在栈内存)

      引用类型:ArrayFunctionObjectRegExpDateMath。(存储在堆内存)

    JS类型检测

      typeof 基础类型正常检测(除了null),引用类型返回'object'(除了function)

      instanceof:基础类型不能检测,引用类型可以正常检测。

      Object.prototype.toString.call(): 基础和引用类型都能检查,返回 "[object Xxxx]"

    JS浅拷贝

      object.assign(target,...sources);

      let cloneObj = {...obj};

      [].concat();

      arr.slice();

      assign和扩展运算缺点:1不能拷贝对象的继承属性。2、不能拷贝对象的不可枚举属性3、可以拷贝 Symbol 属性。

    JS深拷贝

      1、SON.parse(JSON.stringify(x))

      缺点: 函数、undefinedSymbol 序列化会消失;

         Date 会变成字符串;

         RegExp 会变成空对象;

         NaNInfinity-Infinity会变成null

         不能拷贝'不可枚举的属性'

         不能拷贝'对象的原型链'

         不能拷贝'对象的循环引用'

      2、递归for in 遍历参数,typeof是引用类型递归,否则直接赋值)

      缺点: 不能拷贝'不可枚举的数据''Symbol类型'。;

         不能正确拷贝 ArrayDateRegExpErrorFunction 的引用类型;

         不能拷贝'对象的循环引用'

      3、改进递归

        1、不可枚举的属性 及 Symbol类型。可以使用Reflect.ownKeys 方法;

        2、判断参数是 DateRegExp 类型,则直接生成一个新的实例返回;

        3、利用 Object.getOwnPropertyDescriptors() 获得对象的所有属性 以及 对应的特性,结合Object.create() 创建一个新的对象,并继承传入原对象的原型链;

        4、利用 WeakMap 类型作为 Hash 表,因为 WeakMap 是弱引用类型,可以防止内存泄漏,作为检测循环引用很有帮组,如果循环引用则返回 WeakMap 存储的值。

       

    JS继承

      原型链继承

        Child.prototype = new Patent()

        缺点:原型属性共享问题。

      构造函数继承

        Function Child() { Parent.call(this) }

        缺点:不能继承父类原型上的属性和方法

      组合式继承

        原型和构造函数结合

        缺点:父类多构造一次

      原型式继承

        Object.create(parent)

        缺点:多实例中的引用类型属性指向相同的内存

      寄生式继承

        借助方法添加属性和方法。

        Object.create('用作新对象原型的对象','新对象定义额外属性的对象')。

        Let clone = Object.create(original);clone.fun = function(){...};return clone;

        缺点:多实例中引用数据类型属性指向相同的内存

      寄生组合继承

        将parentChild传入clone方法中。减少一次构造的过程。

        Child.prototype = Object.create(parent.prototype);Child.prototype = Child;

      继承中最优的方案

        Es6 extends继承

        使用babel-loader 编译可以看出也是用的寄生组合继承。

    JS  newapplybindcall

      

      new 大致分为以下步骤:

    1. 创建一个新对象;
    2. 将构造函数的作用域赋给新对象(this指向新对象);
    3. 执行构造函数中的代码(为这个对象添加属性);
    4. 返回新对象。
      使用场景:

      (1) 判断数据类型。

        Object.prototype.toString.call([]).replace(/^[object (S+)]$/, '$1')

      (2) 类数组借用方法。
        Array.prototype.push.call({0:'java',1:'script',length:2},'jack','lily')//{0:'java',1:'script',2:'jack',3:'lily',length:4}

      (3) 获取最大/最小值。
        Math.max.apply(Math,[13,6,10,11,16]);// 16
        Math.min.apply(Math,[13,6,10,11,16]);// 6

      (4) 继承
        function child(){ parent.call(this) }
        child.prototype = new parent();
        child.prototype.constructor = child;

    JS 闭包

      全局作用域

        挂在window对象下的变量;未定义直接赋值的变量是全局变量。

        缺点:容易引起‘变量命名的冲突’。

      函数作用域

        函数中定义,在函数内部才能访问到它;函数被执行完,这个局部变量会被销毁。

      块级作用域

        使用let关键字,有‘暂时性死区’特点,定义之前不能被使用。

      闭包

        红宝书:闭包是指有权访问另外一个函数作用域中的变量的函数

        闭包产生的本质就是:当前环境中存在指向父级作用域的引用

        表现形式:1.返回一个函数;2.定时器、事件监听、Ajax请求;3.作为函数参数传递的形式;4.IIFE(立即执行函数)。

        解决循环输出问题:1.利用IIFE2.使用 ES6 中的 let3.定时器传入第三个参数。

    JS 数组

      *构造器

        Array();字面量;Array.of()Array.from()

      *类型判断

        [] instanceof Array;

        [].constructor === Array;

        Array.prototype.isPrototypeOf([]);

        Object.getPrototypeOf([]) === Array.prototype;

        Object.prototype.toString.apply([]) === [object Array]

        Array.isArray([])

      *改变自身的方法

        poppushshiftunshiftreversesortspliceES6 copyWithinfill

      *不改变自身的方法

        concatjoinslicetoStringtoLocaleStringindexOflastIndexOf、为形成标准的toSource,以及ES7 includes

      *遍历的方法

        forEacheverysomefiltermapreducereduceRightES 中的 entriesfindfindIndexkeysvalues

    JS 类数组

      *arguments

        Object.prototype.toString.call(arguments); // [object Arguments]

        callee 属性:被调用函数

      *HTML Collection

        它是HTML DOM 对象的一个接口,返回包含了获取到的 DOM 元素集合,返回的类型是类数组对象。它是及时更新的,当文档中的DOM变化,它会随之变化。
        Object.prototype.toString.call(document.forms[0]); // [object HTMLFormElement]

      *NodeList

        节点集合,由 querySelector 返回的。可以使用 for...of 来迭代。它是实时集合,文档中的节点树发生变化,NodeList 也随之变化。

        var list = document.querySelectorAll(input[type=checkbox]);

        Object.prototype.toString.call(list); // [object NodeList]

      *应用场景

        遍历参数操作

        定义链接字符串函数

          Array.prototype.slice.call(arguments,1).join(separa);

          myConcat(,,red,blue,orange);

        传递参数使用

          bar.apply(this,arguments);

      *类数组转换为数组

        Array.prototype.push.call(arrayLike,jack,lily);

        Array.prototype.slice.call(arguments);

        Array.prototype.concat.apply([],argument);

        Array.from(arguments);

        [...arguments];

    JS数组扁平化

     

    JS 数组排序

      冒泡排序

        两个循环,比较两个元素,调换顺序。

      快速排序

        基线,递归,合并。

      插入排序

        数组本身进行调整。首先循环遍历 i = 0开始,当前值比前面值大,进行交换。

      选择排序

      归并排序

    JS sort实现

      先将元素转换为字符串,然后再进行排序。

      arr.sort([compareFunction]) compareFunction用来执行按某种顺序进行排列的函数,不写元素按照转换为字符串的各个字符的 Unicode 位点进行排序。

      sort 会根据元素个数是 n 分情况排序:

        1.当 n <= 10 时,采用插入排序;

        2.当 n > 10 时,采用三路快速排序;

        3.当 10 < n <= 1000 时,采用中位数最为哨兵元素;

        4.当 n > 1000 时,每隔 200 ~ 215 个元素挑出一个元素,放到一个新数组中,然后对他排序,找到中间位置的数,以此作为中位数。

      当 n 足够小的时候,插入排序的时间复杂度 O(n) 要优于快速排序的 O(nlogn)。因此数据量小的时候会采用插入排序

    JS 异步编程方案

      *回调函数

        问题:回调地狱

      *Promise

        优点:可以将异步操作以同步操作的流程表达出来,避免层层嵌套的回调函数。

        缺点:使用 Promise 链式调用过多,其根本上没有解决回调地狱,依然难以维护。不过Promise 提供了 all 方法。

        一个 Promise 有三种状态:pending、fulfilled 和 rejected。

      *Generator

        特点:交出函数的执行权,需要暂停的方法可以用 yield 标注,返回的是迭代器。

        使用 * 来标注它是Generator 函数,next()依次调用,最后返回”{value:undefined,done:true}”的结果,标识该Generator 函数已经执行完毕。

      *async/await

        ES7提供新的一步方案:async/await。Async 是 Generator 函数的语法糖;写起来使得 JS 的异步代码像同步。

    JS 代码是如何被浏览器引擎编译、执行的?

    通过V8引擎,先把js代码转化成AST,然后通过解释器将AST转成字码节,在通过编译器将字码节转成机器码,最后在进行垃圾回收, 至此整个js就的执行就完成了。

  • 相关阅读:
    python基础总结二
    HTTP和HTTPS的区别
    通过HTTP请求响应过程了解HTTP协议
    稳定性测试+易用性测试
    容错测试点
    功能测试思考点
    功能测试-UI测试思考点
    字符编码-11
    字典+再识函数-8
    web API的概念
  • 原文地址:https://www.cnblogs.com/wenshaochang123/p/15379674.html
Copyright © 2011-2022 走看看