每日五道前端面试题--day1

以下题目来自掘金等其它博客,但是问题的答案都是根据笔者自己的理解做出的。如果你最近想要换工作或者巩固一下自己的前端知识基础,不妨和我一起参与到每日刷题的过程中来,如何?

第一天要刷的面试题如下:

  1. js中的数据类型检测方法都有哪些?
  2. 判断x为数组的方法都有哪些?
  3. null和undefined的区别是什么?
  4. typeof null的结果是什么?为什么?
  5. 手写一个函数实现instanceof操作符的功能

下面是我自己的理解:

1. js中的数据类型检测方法都有哪些?

首先,用于检测js中数据类型的方法一般来说有四种,分别为:tyepof x, x instanceof y, x.constructor?.name, Object.prototype.toString.call(x).slice(8, -1); 前两个是操作符,中间的是属性,而最后一个是方法。

  1. 先说typeof: typeof x的返回值可能为:'object' 'undefined' 'number' 'string' 'symbol' 'bigint' 'boolean' 'function'。注意它们都是首字母小写的字符串。
  • 使用typeof x 判断类型有两个问题,问题一在于:对null的判断结果是'object',这个是不正确的;第二个问题是:只能判断出对象的类型为'object',无法进一步得到更加具体的结论。
  • typeof x有一个优点那就是在判断基本类型的时候非常的方便(除了null),并且在判断'function'类型的时候也非常方便(唯一一个给出具体类型的object)。
  • 对于typeof x判断方法的缺点的处理方法就是采用更加合适的其它判别方法。
  1. x instanceof y判别方法的问题在于只对object类型生效,只能判断表达式是否成立,而不能直接告诉调用者到底是谁。其原理是通过原型链查找,所以y只要在x的原型链上都会返回true,总之这种判别法只能用来排除,因为给出的结论都是模糊性的。
  2. ?.constructor?.name这种方法对于对象类型和包装类型都生效,返回的是首字母大写的字符串。缺点在于无法分辨null和undefined,并且constructor属性值可以被篡改。不考虑其缺点的时候比typeof好用一些。
  3. 最后的Object.prototype.toString.call(x).slice(8, -1)方法是王炸,是唯一一种能够判断出null数据类型的方法。返回值为首字母大写的字符串,列举其可能的返回值:'String' 'Null' 'Undefined' 'Number' 'String' 'Symbol' 'Bigint' 'Boolean' 'Array' 'Date' 'RegExp' 'Error' 'Function'。可惜这个方法还是有缺点的const a = {}; a可以通过修改[Symbol.toStringTag]的值改变此方法的返回值。

总结下来,这四个方法各有各的用武之地,但是如果想要清晰的知道x的类型的话,推荐使用最后一种方式。

2. 判断x为数组的方法都有哪些?

总结下来就是:toString方法,ES6方法和原型相关的方法。

    1. Object.prototype.toString.call(x).slice(8, -1) === "Array";
    1. Array.isArray(x);
    1. x instanceof Array;
    1. x.__proto__ == Array.prototype;
    1. x.constructor.name === "Array";
    1. Array.prototype.isPrototypeof(x);

有条件的话使用第二个,后面四个实际上都是与原型有关的方法;一句话的不同说法罢了。

3. null和undefined的区别是什么?

null和undefined的区别可以通过以下四点说明:

  1. 从语义上:null表示有值,但是值为空,而undefined则表示没有值。
  2. 从语法上:形参或者变量的值为null的时候并不会触发默认值,但是如果值为undefined会强制触发默认值。
  3. typeof检测的时候,一个结果是正确的,另外一个结果不正确。
  4. 两者虽然都是基本类型,但是undefined不是保留字,这意味着你可以为其赋值,或者声明其为变量,这是不安全的,所以一般使用void 0作为undefined的替代。

4. typeof null的结果是什么?为什么?

  • 计算结果为:"object",之所以出现这个结果,源自js这门编程语言设计之初的规定。
  • 在js第一版的时候,所有的数据都是存放在一个32bit的存储空间中,这32bit被划分成两个部分,一个是用来表示类型的,通常占0-3个bit,剩下的部分则都是用来表示数据的。
  • 为什么是0-3个bit位表示类型呢?因为当时表示int类型的是1,没错只有一位,所以对于整数来说剩下的31位都可以用来表示数据;而对于string类型,标识符则为100,有三个bit位;double类型的是010;boolean则为110;而object的类型则是用000三个bit位进行表示;
  • 除了上面这些,undefined用一个溢出的整数来表示,所以它没有标识位,为0位;而对于null,js简单粗暴的使用机器码NULL,但是机器码NULL本身是32个0。
  • 注意32个0意味着前三位也是0,所以typeof null的时候null会被当成object,所以结果返回的是'object'。

5. 手写一个函数实现instanceof操作符的功能

  • x instanceof y 的作用原理就是,在x的原型链上寻找y,如果找到了就返回true,如果找不到就返回false;
  • 根据其作用原理,其实现过程也就呼之欲出了:首先判断x是不是object类型的,如果不是直接返回false就可以了。如果是的话,则逐级比较x的原型和y是否相等,知道x原型链的尽头,也就是null。如果此时y与任何一层原型都不相等,则返回false,否则返回true。
  • 实现代码如下:
javascript 复制代码
function myInstanceof(obj, cons){
    if(Object(obj)!==obj) return false;
    let _p = obj.__proto__;
    while(_p!==null){
      if(_p==cons.prototype) return true;
      _p = _p.__proto__;
    }
    return false;
}
相关推荐
用泥种荷花17 分钟前
Python环境安装
前端
Light6027 分钟前
性能提升 60%:前端性能优化终极指南
前端·性能优化·图片压缩·渲染优化·按需拆包·边缘缓存·ai 自动化
Jimmy31 分钟前
年终总结 - 2025 故事集
前端·后端·程序员
烛阴33 分钟前
C# 正则表达式(2):Regex 基础语法与常用 API 全解析
前端·正则表达式·c#
roman_日积跬步-终至千里39 分钟前
【人工智能导论】02-搜索-高级搜索策略探索篇:从约束满足到博弈搜索
java·前端·人工智能
GIS之路1 小时前
GIS 数据转换:使用 GDAL 将 TXT 转换为 Shp 数据
前端
多看书少吃饭1 小时前
从Vue到Nuxt.js
前端·javascript·vue.js
前端一小卒1 小时前
从 v5 到 v6:这次 Ant Design 升级真的香
前端·javascript
yaoh.wang1 小时前
力扣(LeetCode) 88: 合并两个有序数组 - 解法思路
python·程序人生·算法·leetcode·面试·职场和发展·双指针
前端不太难2 小时前
《Vue 项目路由 + Layout 的最佳实践》
前端·javascript·vue.js