Auc的个人博客

vuePress-theme-reco Auc    2020 - 2021
Auc的个人博客 Auc的个人博客

选择一个主题吧~

  • 暗黑
  • 自动
  • 明亮
主页
分类
  • JavaScript
  • Vue
  • 数据结构与算法
  • 文档
  • 面试题
  • 笔记
标签
笔记
  • CSS
  • ES6
  • JavaScript
  • Vue
  • C语言
文档
  • Vueのapi
  • Vue Router
  • axios
  • Vue CLI
面试
  • JS
  • Vue
  • 基础
时间线
联系我
  • GitHub (opens new window)
author-avatar

Auc

62

文章

11

标签

主页
分类
  • JavaScript
  • Vue
  • 数据结构与算法
  • 文档
  • 面试题
  • 笔记
标签
笔记
  • CSS
  • ES6
  • JavaScript
  • Vue
  • C语言
文档
  • Vueのapi
  • Vue Router
  • axios
  • Vue CLI
面试
  • JS
  • Vue
  • 基础
时间线
联系我
  • GitHub (opens new window)
  • JS

    • 一道 arrayLike 的面试题

一道 arrayLike 的面试题

vuePress-theme-reco Auc    2020 - 2021

一道 arrayLike 的面试题

Auc 2020-03-11 JavaScript面试题
var obj = {
    '2': 3,
    '3': 4,
    'length': 2,
    'splice': Array.prototype.splice,
    'push': Array.prototype.push
}
obj.push(1);
obj.push(2);
console.log(obj); 
1
2
3
4
5
6
7
8
9
10

考察

本题考查类数组、push方法以及length属性的应用

# 解析

  1. 首先定义了一个对象并将地址传递给了变量 obj

观察对象,拥有 length 属性并且是其值为正整数,以及 splice 属性,并且其值对应函数(详见本题第二、三部分证明),所以可以被解析成类数组。

  1. 既然是类数组,对象的键就是数组的下标,对象的值就是数组当前下标的值

此时撇开 length 属性不管,这个类数组可以看作:[empty, empty, 3, 4]

贴士

介绍 push() 方法:它会根据 length 属性来决定从哪里开始插入给定的值,详见 MDN (opens new window)

  1. 所以当执行 push(1) 时,length 属性起作用,它将这个类数组的长度截断了,此时可以看作:[empty, empty]

  2. 之后进行了两次push操作,结果可以看作:[empty, empty, 1, 2],

然后类数组length属性更新为4。

  1. 打印结果:[empty × 2, 1, 2, splice: ƒ, push: ƒ]

# 查阅 Chrome DevTools

我去查阅了开发者工具文档,详见ChromeDevTools (opens new window),得到如下结论:

判断 arrayLike 的机制

  1. 存在且是对象
  2. 对象上的 splice 属性是函数类型
  3. 对象上有 length 属性且为正整数
function isArrayLike(obj) {
    if (!obj || typeof obj !== 'object') {
        return false;
    }
    try {
        if (typeof obj.splice === 'function') {
            const len = obj.length;
            return typeof len === 'number' && (len >>> 0 === len && (len > 0 || 1 / len > 0));
        }
    } catch (e) {
    }
    return false;
}
1
2
3
4
5
6
7
8
9
10
11
12
13

# 一次手段不聪明的证明

用不聪明的办法验证一个对象的 length 属性为 正整数 ,同时 splice 属性为函数时,对象的函数输出结果就会变成类数组。

//1. length对应数字,splice对应函数(这里只用了空函数)
var obj1 = {
    length: 1,
    splice: function () { },
}; 
// 打印结果:Object [empty, splice: ƒ] ===> 类数组

//2. length对应字符串,splice对应函数
var obj2 = {
    length: '1',
    splice: function () { },
}; 
// 打印结果:{length: "1", splice: ƒ}  ===> 对象

//3. length对应数字,splice对应空对象
var obj3 = {
    length: 1,
    splice: {},
}; 
// 打印结果:{length: 1, splice: {…}}  ===> 对象

//4. length对应数字,但是为负数;splice对应函数
var obj4 = {
    length: -1,
    splice: function () { },
}; 
//打印结果:{length: "-1", splice: ƒ} ===> 对象

console.log(obj1, obj2, obj3, obj4);
//综上:结论成立
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30