美文网首页
前端基础之JS(二)

前端基础之JS(二)

作者: 若雨千寻 | 来源:发表于2023-12-07 09:13 被阅读0次

1.16 instanceOf作用 即原理

instanceof主要作用就是判断一个实例是否属于某种类型

function new_instance_of(leftVaule, rightVaule) {
    let rightProto = rightVaule.prototype; // 取右表达式的 prototype 值
    leftVaule = leftVaule.__proto__; // 取左表达式的__proto__值
    while (true) {
        if (leftVaule === null) {
            return false;
        }
        if (leftVaule === rightProto) {
            return true;
        }
        leftVaule = leftVaule.__proto__
    }
}

其实 instanceof 主要的实现原理就是只要右边变量的 prototype 在左边变量的原型链上即可。因此,instanceof 在查找的过程中会遍历左边变量的原型链,直到找到右边变量的 prototype,如果查找失败,则会返回 false,告诉我们左边变量并非是右边变量的实例。

1.17 数组和伪数组的区别?

  1. 定义
  • 数组是一个特殊对象,与常规对象的区别:
    • 当由新元素添加到列表中时,自动更新length属性
    • 设置length属性,可以截断数组
    • 从Array.protoype中继承了方法
    • 属性为'Array'
  • 类数组是一个拥有length属性,并且他属性为非负整数的普通对象,类数组不能直接调用数组方法。
  1. 区别
    本质:类数组是简单对象,它的原型关系与数组不同
    let arrayLike = {
        length: 10,
    };
    console.log(arrayLike instanceof Array); // false
    console.log(arrayLike.__proto__.constructor === Array); // false
    console.log(arrayLike.toString()); // [object Object]
    console.log(arrayLike.valueOf()); // {length: 10}
    let array = [];
    console.log(array instanceof Array); // true
    console.log(array.__proto__.constructor === Array); // true
    console.log(array.toString()); // ''
    console.log(array.valueOf()); // []
  1. 类数组转换为数组
  • 转换方法
    • 使用 Array.from()
    • 使用 Array.prototype.slice.call()
    • 使用 Array.prototype.forEach() 进行属性遍历并组成新的数组
  • 转换须知
    • 转换后的数组长度由 length 属性决定。索引不连续时转换结果是连续的,会自动补位
    let al1 = {
        length: 4,
        0: 0,
        1: 1,
        3: 3,
        4: 4,
        5: 5,
    };
    console.log(Array.from(al1)) // [0, 1, undefined, 3]
    // 2.仅考虑 0或正整数 的索引
    let al2 = {
        length: 4,
        '-1': -1,
        '0': 0,
        a: 'a',
        1: 1
    };
    console.log(Array.from(al2)); // [0, 1, undefined, undefined]
    // 3.使用slice转换产生稀疏数组
    let al2 = {
        length: 4,
        '-1': -1,
        '0': 0,
        a: 'a',
        1: 1
    };
    console.log(Array.prototype.slice.call(al2)); //[0, 1, empty × 2]
    // 4.使用数组方法操作类数组注意地方
    let arrayLike2 = {
        2: 3,
        3: 4,
        length: 2,
        push: Array.prototype.push
    }
    // push 操作的是索引值为 length 的位置
    arrayLike2.push(1);
    console.log(arrayLike2); // {2: 1, 3: 4, length: 3, push: ƒ}
    arrayLike2.push(2);
    console.log(arrayLike2); // {2: 1, 3: 2, length: 4, push: ƒ}

1.18 介绍下 Set、Map、WeakSet 和 WeakMap的区别?

Set

  1. 成员不能重复;
  2. 只有键值,没有键名,有点类似数组;
  3. 可以遍历,方法有 add、delete、has

WeakSet

  1. 成员都是对象(引用);
  2. 成员都是弱引用,随时可以消失(不计入垃圾回收机制)。可以用来保存 DOM 节点,不容易造成内存泄露;
  3. 不能遍历,方法有 add、delete、has ;

Map

  1. 本质上是键值对的集合,类似集合;
  2. 可以遍历,方法很多,可以跟各种数据格式转换;

WeakMap

  1. 只接收对象为键名(null 除外),不接受其他类型的值作为键名;
  2. 键名指向的对象,不计入垃圾回收机制;
  3. 不能遍历,方法同 get、set、has、delete ;

1.19 简单说说 js 中有哪几种内存泄露的情况

  1. 意外的全局变量;
  2. 闭包;
  3. 未被清空的定时器;
  4. 未被销毁的事件监听;
  5. DOM 引用;

1.20 json和xml数据的区别?

  1. 数据体积方面:xml是重量级的,json是轻量级的,传递的速度更快些。
  2. 数据传输方面:xml在传输过程中比较占带宽,json占带宽少,易于压缩。
  3. 数据交互方面:json与javascript的交互更加方便,更容易解析处理,更好的进行数据交互
  4. 数据描述方面:json对数据的描述性比xml较差
  5. xml和json都用在项目交互下,xml多用于做配置文件,json用于数据交互。

1.21 JavaScript有几种方法判断变量的类型?

  1. 使用typeof检测当需要判断变量是否是number, string, boolean, function, undefined等类型时,可以使用typeof进行判断。
  2. 使用instanceof检测instanceof运算符与typeof运算符相似,用于识别正在处理的对象的类型。与typeof方法不同的是,instanceof 方法要求开发者明确地确认对象为某特定类型。
  3. 使用constructor检测constructor本来是原型对象上的属性,指向构造函数。但是根据实例对象寻找属性的顺序,若实例对象上没有实例属性或方法时,就去原型链上寻找,因此,实例对象也是能使用constructor属性的。

1.22 Math.min()< Math.max()

false
按常规的思路,这段代码应该输出 true,毕竟最小值小于最大值。但是却输出 false

1.23 promise和 async await 区别?

概念
Promise 是异步编程的一种解决方案,比传统的解决方案——回调函数和事件——更合理和更强
大,简单地说,Promise好比容器,里面存放着一些未来才会执行完毕(异步)的事件的结果,而
这些结果一旦生成是无法改变的
async await也是异步编程的一种解决方案,他遵循的是Generator 函数的语法糖,他拥有内置执
行器,不需要额外的调用直接会自动执行并输出结果,它返回的是一个Promise对象
两者的区别

  1. Promise的出现解决了传统callback函数导致的“地域回调”问题,但它的语法导致了它向纵向
    发展行成了一个回调链,遇到复杂的业务场景,这样的语法显然也是不美观的。而async
    await代码看起来会简洁些,使得异步代码看起来像同步代码,await的本质是可以提供等同
    于”同步效果“的等待异步返回能力的语法糖,只有这一句代码执行完,才会执行下一句。
  2. async await与Promise一样,是非阻塞的。
  3. async await是基于Promise实现的,可以说是改良版的Promise,它不能用于普通的回调函
    数。

1.24 defer和async区别?

  • defer要等到整个页面在内存中正常渲染结束(DOM结构完全生成,以及其他脚本执行完成),才会执行。多个defer脚本会按照它们在页面出现的顺序加载。==“渲染完再执行”==
  • async一旦下载完,渲染引擎就会中断渲染,执行这个脚本以后,再继续渲染。多个async脚本是不能保证加载顺序的。==“下载完就执行”==

1.25 同步和异步

同步

  • 指在 主线程上排队执行的任务,只有前一个任务执行完毕,才能继续执行下一个任务。
  • 也就是调用一旦开始,必须这个调用 返回结果(划重点——)才能继续往后执行。程序的执行顺序
    和任务排列顺序是一致的。

异步

  • 异步任务是指不进入主线程,而进入 任务队列的任务,只有任务队列通知主线程,某个异步任务可以执行了,该任务才会进入主线程。
  • 每一个任务有一个或多个 回调函数。前一个任务结束后,不是执行后一个任务,而是执行回调函数,后一个任务则是不等前一个任务结束就执行。
  • 程序的执行顺序和任务的排列顺序是不一致的,异步的。
  • 我们常用的setTimeout和setInterval函数,Ajax都是异步操作。

1.26 javascript中arguments相关的问题?

arguments

在js中,我们在调用有参数的函数时,当往这个调用的有参函数传参时,js会把所传的参数全部存到一个叫arguments的对象里面。它是一个类数组数据

由来

Javascrip中每个函数都会有一个Arguments对象实例arguments,引用着函数的实参。它是寄生在js函数当中的,不能显式创建,arguments对象只有函数开始时才可用

作用

有了arguments这个对象之后,我们可以不用给函数预先设定形参了,可以动态地通过arguments为函数加入参数

1.27 null 和 undefined 的区别,如何让一个属性变为null

undefined

  1. 声明了一个变量,但没有赋值
  2. 访问对象上不存在的属性
  3. 函数定义了形参,但没有传递实参
  4. 使用 void 对表达式求值

null

  1. null是一个空值
  2. null 有属于自己的类型 Null,而不属于Object类型
  3. 二进制的前三位为 0 会被 typeof 判断为对象类型

1.28 简单说说 js 中有哪几种内存泄露的情况

  1. 意外的全局变量;
  2. 闭包;
  3. 未被清空的定时器;
  4. 未被销毁的事件监听;
  5. DOM 引用;

1.29 call appy bind的作用和区别?

作用:

都可以改变函数内部的this指向

区别点:

  1. call 和 apply 会调用函数,并且改变函数内部this指向。
  2. call 和 apply 传递的参数不一样,call 传递参数arg1,arg2...形式 apply 必须数组形式[arg]
  3. bind 不会调用函数,可以改变函数内部this指向

1.30 this指向(普通函数、箭头函数)

  1. 谁调用了函数或者方法,那么这个函数或者对象中的this就指向谁
  2. 匿名函数中的this:匿名函数的执行具有全局性,则匿名函数中的this指向是window,而不是调用该匿名函数的对象

箭头函数中的this

  • 箭头函数中的this是在函数定义的时候就确定下来的,而不是在函数调用的时候确定的
  • 箭头函数中的this指向父级作用域的执行上下文;
  • 箭头函数无法使用apply、call和bind方法改变this指向,因为其this值在函数定义的时候就被确定下来

相关文章

网友评论

      本文标题:前端基础之JS(二)

      本文链接:https://www.haomeiwen.com/subject/jdedgdtx.html