JavaScript数据结构常见面试问题整理

 更新时间:2022年08月04日 15:15:25   作者:饭啊饭°  
在JavaScript中,数据结构是指相互之间存在一种或多种特定关系的数据元素的集合,是带有结构特性的数据元素的集合。常用的数据结构有:数组、列表、栈、队列、链表、字典、集合等等

1.JS有哪些数据类型有什么区别

答:JS共有八大数据类型,分别是:String、Number、Boolean、Object、Null、Undefined、Symbol、BigInt。其中Symbol(独一无二不可变)和BigInt(任意精度的数字)是ES6中新加入的数据类型。这些数据类型可以分为原始数据类型(String、Number、Boolean、Null、Undefined)和引用数据类型(Object、数组、函数等)。

**区别:**存储位置不同 原始数据类型直接存储在栈(stack)中的简单数据段,占据空间、大小固定,属于被频繁使用的数据,所以放在栈中存储;引用数据类型存储在堆中的对象,占据空间大、大小不固定,如果存储在栈中,将会影响程序运行的性能。

  • 在数据结构中,栈中数据的存取方式为先进后出。
  • 堆是一个优先队列,是按优先级来进行排序的,优先级可以按照大小来规定。

2.数据类型检测的方式

答:JavaScript有4种方法判断变量的类型,分别是typeof、instanceof、Object.prototype.toString.call()(对象原型链判断方法)、 constructor (用于引用数据类型) 。typeof:常用于判断基本数据类型,对于引用数据类型除了function返回’function‘,其余全部返回’object’。 instanceof:主要用于区分引用数据类型,检测方法是检测的类型在当前实例的原型链上,用其检测出来的结果都是true,不太适合用于简单数据类型的检测,检测过程繁琐且对于简单数据类型检测不出来。 constructor:用于检测所有数据类型,检测方法是获取实例的构造函数判断和某个类是否相同,如果相同就说明该数据是符合那个数据类型的,这种方法不会把原型链上的其他类也加入进来,避免了原型链的干扰。 Object.prototype.toString.call():适用于所有类型的判断检测,检测方法是Object.prototype.toString.call(数据) 返回的是该数据类型的字符串。 这四种判断数据类型的方法中,各种数据类型都能检测且检测精准的就是Object.prototype.toString.call()这种方法。

加分回答 instanceof的实现原理:验证当前类的原型prototype是否会出现在实例的原型链__proto__上,只要在它的原型链上,则结果都为true。因此,instanceof 在查找的过程中会遍历左边变量的原型链,直到找到右边变量的 prototype,找到返回true,未找到返回false。 Object.prototype.toString.call()原理:Object.prototype.toString 表示一个返回对象类型的字符串,call()方法可以改变this的指向,那么把Object.prototype.toString()方法指向不同的数据类型上面,返回不同的结果

(1)typeof:返回数据的类型,但是数组、null、对象、函数,都只能返回object,所以typeof并不能区分出处理function的其他object中的几种不同类型。

console.log(typeof 2);               // number
console.log(typeof true);            // boolean
console.log(typeof 'str');           // string
console.log(typeof []);              // object    
console.log(typeof function(){});    // function
console.log(typeof {});              // object
console.log(typeof undefined);       // undefined
console.log(typeof null);            // object

衍生问题:为什么typeof null 是obect ?

原因是:在JS的第一个版本中,所有值都存储在32位的单元中,每个单元包含一个小的类型标签,以及当前要存储的真实数据,类型标签包括000(object)、1(int)、010(double)、100(string)、110(boolean)。而null的机器码全是0,所以被认为是object。

(2)instanceof:可以判断instanceof后面的类型是否正确,返回true / false,内部的运行机制是看能不能在原型链中找到该类型的原型。但是instanceof只能判断出引用数据类型,并且可以区分出数组、函数等,却不能判断基本数据类型。

console.log(2 instanceof Number);                    // false
console.log(true instanceof Boolean);                // false 
console.log('str' instanceof String);                // false 
console.log([] instanceof Array);                    // true
console.log(function(){} instanceof Function);       // true
console.log({} instanceof Object);                   // true

(3)constructor可以判断数据类型,还可以访问对象的构造函数。constructor可以把object分开来判断。分为(Array、Function、object)

console.log((2).constructor === Number); // true
console.log((true).constructor === Boolean); // true
console.log(('str').constructor === String); // true
console.log(([]).constructor === Array); // true
console.log((function() {}).constructor === Function); // true
console.log(({}).constructor === Object); // true

(4)Object.prototype.toString.call():使用Object对象的原型方法toString来判断数据类型

var a = Object.prototype.toString;
console.log(a.call(2));  //[object Number]
console.log(a.call(true)); //[object Boolean]
console.log(a.call('str')); //[object String]
console.log(a.call([])); //[object Array]
console.log(a.call(function(){})); //[object Function]
console.log(a.call({})); //[object Object]
console.log(a.call(undefined)); //[object Undefined]
console.log(a.call(null)); //[object Null]

3.判断是否是数组的方法

var b = new Array();
console.log(b instanceof Array); //true
console.log(Object.prototype.toString.call(b)); //[object Array]
console.log(Array.isArray(b)); //true
console.log(b.constructor===Array); //true
console.log(b.__proto__===Array.prototype); //true
console.log(Array.prototype.isPrototypeOf(b)); //true

4.null和undefined的区别

答:undefind 是全局对象的一个属性,当一个变量没有被赋值或者一个函数没有返回值或者某个对象不存在某个属性却去访问或者函数定义了形参但没有传递实参,这时候都是undefined。undefined通过typeof判断类型是’undefined’。undefined == undefined undefined === undefined 。 null代表对象的值未设置,相当于一个对象没有设置指针地址就是null。null通过typeof判断类型是’object’。null === null null == null null == undefined null !== undefined undefined 表示一个变量初始状态值,而 null 则表示一个变量被人为的设置为空对象,而不是原始状态。在实际使用过程中,不需要对一个变量显式的赋值 undefined,当需要释放一个对象时,直接赋值为 null 即可。 让一个变量为null,直接给该变量赋值为null即可。typeof null是object。

undefined == null   //true
undefined === null  //false
undefined !== null  //true

5.手写instanceof方法

function myInstanceof(left,right){
    let proto = Object.getPrototypeOf(left)
    let prototype = right.prototype;
    while(true){
        if(!proto) return false
        if(proto === prototype) return true
        proto = Object.getPrototypeOf(proto)
    }
}
console.log(myInstanceof("",Array)); //false
console.log(myInstanceof([1,2,3],Array)); //true

6.为什么0.1+0.2 !==0.3

答:首先要知道小数是如何转为二进制的,整数部分就是不断除2取余,小数部分就是乘二取整,超过1以后还是用小数部分乘,如下所示:

//不断的乘以二然后拿掉整数部分,直到积为0。
//但是结果是不可能为0的,所以是循环的
0.1 * 2 = 0.2 => 0
0.2 * 2 = 0.4 => 0
0.4 * 2 = 0.8 => 0
0.8 * 2 = 1.6 => 1
0.6 * 2 = 1.2 => 1
0.2 * 2 = 0.4 => 0

因此,0.1的二进制是0.0001 1001 1001 1001…无限循环,0.2的二进制是0.0011 0011 0011 0011…无限循环,所以0.3的二进制就是0.0100 1100 1100 1100 1100 1100 1100 1100 1100 1100 1100 1100 1100,转换为十进制就是0.300000004,这就是精度丢失问题,所以0.1+0.2 !== 0.3。可以用toFixed(1)来解决,但也要注意,toFixed()返回的类型是String。

7.isNaN和Number.isNaN函数的区别

  • isNaN接受参数后,会尝试将这个参数转换为数值,任何不能转换的都会返回true,因此,非数字值传入也会返回true,会影响NaN的判断。
  • Number.isNaN会首先判断传入参数是否是数字,如果是数字再继续判断是否为NaN,不会进行数据类型的转换,更加准确。
console.log(isNaN(NaN)) //true
console.log(isNaN("123")); //false
console.log(isNaN("NaN")); //true
console.log(Number.isNaN(NaN)); //true
console.log(Number.isNaN("123")); //false
console.log(Number.isNaN("NaN")); //false

8.==操作符的强制类型转换规则

(1)类型相同的话就直接比较;

(2)类型不同的话,会进行类型转换;

(3)先判断是不是null 和 undefined,是的话就返回true;

(4)判断是否是string 和 number,string --> number;

(5)如果有一方是boolean,那么boolean --> number;

(6)如果一方是object,另一方是string number symbol,把object–> 原始类型。

console.log(NaN == NaN);    //false
console.log(null instanceof Object);   //false 因为null是原型链的顶端了,而instanceof是根据Object.getPrototypeof()实现的,找不到他的父类了
console.log(null == null);  //true
console.log(false == "");   //true
console.log(undefined == false);    //false

9.强制转换的规则

(1)其他值–>字符串:Null、Undefined、Boolean、Number、Symbol都是直接转换为字符串,加上双引号,对于普通对象来说,一般会用toString()转换为内部属性[[Class]]的值;

(2)其他值–>数字值:①Undefined类型的值转换为NaN,Null类型转换为0,true为1,false为0,String如果包含非数字就为NaN,否则为数字,空字符串为0,Symbol会报错;

(3)其他值–>布尔值:false值包括(undefined,null,false,+0,-0,NaN,“”),其他值都是真值。

10.Object.is()与比较操作符===和==的区别

答:==在进行判断时,如果两边类型不一致,会进行转换,转换以后再比较;===如果两边类型不一致,就不会进行强制类型转换,直接返回false;Object.is()一般情况下和三等号相同,但是-0和+0不再相等,两个NaN是相等的。

到此这篇关于JavaScript数据结构常见面试问题整理的文章就介绍到这了,更多相关JavaScript数据结构内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 微信小程序实现的一键复制功能示例

    微信小程序实现的一键复制功能示例

    这篇文章主要介绍了微信小程序实现的一键复制功能,结合实例形式分析了微信小程序wx.setClipboardData接口实现操作粘贴板进行复制操作的相关使用技巧,需要的朋友可以参考下
    2019-04-04
  • JS字符串拼接在ie中都报错的解决方法

    JS字符串拼接在ie中都报错的解决方法

    最近用js拼接字符串时遇到问题了,不论怎么拼接在ie中都报错,于是找到了一个不错的解决方法,在此与大家分享下
    2014-03-03
  • JS实现基数排序的示例代码

    JS实现基数排序的示例代码

    基数排序是一种根据数字位数的值,对整数进行排序的算法,本文主要介绍了JS实现基数排序的示例代码,具有一定的参考价值,感兴趣的可以了解一下
    2023-12-12
  • JS设计模式之状态模式的用法使用方法

    JS设计模式之状态模式的用法使用方法

    JavaScript状态模式是一种行为型设计模式,核心是对象在其内部状态改变时改变其行为,状态模式将对象的行为封装到不同的状态类中,使得对象在不同状态下可以选择不同的行为,本文给大家详细的介绍一下状态设计模式在Js中的使用,需要的朋友可以参考下
    2023-08-08
  • js移动端图片压缩上传功能

    js移动端图片压缩上传功能

    这篇文章主要为大家详细介绍了js移动端图片压缩上传功能,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-09-09
  • js中substring和substr的详细介绍与用法

    js中substring和substr的详细介绍与用法

    这篇文章介绍了js中substring和substr的用法,有需要的朋友可以参考一下
    2013-08-08
  • 什么是JavaScript注入攻击?

    什么是JavaScript注入攻击?

    本文告诉大家什么是js注入,讨论防止 ASP.NET MVC 应用程序受到 JavaScript 注入攻击的两种技术,感兴趣的小伙伴们可以参考一下
    2016-09-09
  • JS如何循环遍历JSON数据

    JS如何循环遍历JSON数据

    这篇文章主要介绍了JS如何循环遍历JSON数据的方法,本文提供了 JS 循环 JSON 数据列,以及 JS 循环遍历 JSON 数据的例子,需要的朋友可以参考下
    2024-01-01
  • 去除图像或链接黑眼圈的两种方法总结

    去除图像或链接黑眼圈的两种方法总结

    去除图像或链接黑眼圈的两种方法总结...
    2007-06-06
  • js操作XML文件的实现方法兼容IE与FireFox

    js操作XML文件的实现方法兼容IE与FireFox

    下面小编就为大家带来一篇js操作XML文件的实现方法兼容IE与FireFox。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2016-06-06

最新评论