JavaScript面经

这篇具有很好参考价值的文章主要介绍了JavaScript面经。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

延迟加载js有哪些方式?

数据类型有哪些?

null和undefined的区别

数据类型检测的方式有哪些?

(1)typeof

(2)instanceof

(3)constructor

(4)Object.prototype.toString.call()

判断数组的方式有哪些

通过Object.prototype.toString.call()做判断

通过原型链做判断

通过ES6的Array.isArray()做判断

通过instanceof判断

通过Array.prototype.isPrototypeOf()判断

typeof null的结果是什么,为什么?

为什么0.1+0.2!==0.3,如何让其相等

JS数组去重

方式一:new set

方式二:indexOf

方式三:sort

let、const、var的区别

队列

链表

链表和数组的区别

字典

二叉树

结构

二叉树前序遍历

前序遍历 栈版本  非递归版本

二叉树中序遍历

中序遍历 栈版本  非递归版本

后序遍历

后序遍历 栈版本  非递归版本


延迟加载js有哪些方式?

     延迟加载 : async、defer
    defer : 等html全部解析完成,才会执行js代码,顺次执行js脚本.
    async : async是和html解析同步的(一起的),不是顺次执行js脚本(谁先加载完谁先执行)

数据类型有哪些?

基本类型:string、number、boolean、undefined、null、symbol、bigint
引用类型:object
NaN是一个数值类型,但是不是一个具体的数字。

null和undefined的区别

    1.作者在设计js的都是先设计null(为什么设计了null:最初设计js的时候借鉴了java的语言)

    2.null会被演示转化成0,很不容易发现错误.

    3.先有null后有undefined是为了填补之前的坑.

    具体区别:JavaScript的最初版本是这样区分的:

      null是一个表示"无"的对象(空对象指针),转为数值是0;

      undefined,转为数值时为NaN

 null本质是一个指针,指向一个空的对象,作用是js引擎用来垃圾回收,undefined是未初始化变量的默认值,作用是区分空变量和未初始化的变量. 简单来说,undefined 是一个空的变量,null是一个空的对象.

数据类型检测的方式有哪些?

(1)typeof

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

其中数组、对象、null都会被判断为object,其他判断都正确。

(2)instanceof

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 0bject);              // true

可以看到,instanceof只能正确判断引用数据类型,而不能判断基本数据类型。instanceof运算符可以用来测试一个对象在其原型链中是否存在一个构造函数的prototype属性。

(3)constructor

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

constructor有两个作用,一是判断数据的类型,二是对象实例通过constructor对象访问它的构造函数。需要注意,如果创建一个对象来改变它的原型,constructor就不能用来判断数据类型了:

function Fn(){};
​
Fn.prototype = new Array();
​
var f = new Fn();
​
console.log(f.constructor === Fn);    //false
console.log(f.constructor === Array); //true

(4)Object.prototype.toString.call()

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

var a = object.prototype.toString;
console.log(a.ca1l(2));
console.log(a.call(true));
console.log(a.call('str'));
console.log(a.call([]));
console.log(a.call(function(){}));
console.log(a.call({}));
console.log(a.call(undefined));
console.log(a.call(null));

同样是检测对象obj调用toString方法,obj.toString()的结果和Object.prototype.toString.call(obj)的结果不一样,者是为什么?

这是因为toString是Object的原型方法,而Array、function等类型作为Object的实例,都重写了toString方法。不同的对象类型调用toString方法时,根据原型链的知识,调用的是对应的重写之后的toString方法(function类型返回内容为函数体的字符串,Array类型返回元素组成的字符串),而不会去调用Object上原型toString方法(返回对象的具体类型),所以采用obj.toString()不能得到其对象类型,只能将obj转换为字符串类型;因此,在想要得到对象的具体类型时,应该调用Object原型上的toString方法。

判断数组的方式有哪些

  • 通过Object.prototype.toString.call()做判断

    Object.prototype.toString.call(obj).slice(8,-1) === 'Array';
  • 通过原型链做判断

    obj.__proto__ === Array.prototype
  • 通过ES6的Array.isArray()做判断

    Array.isArray(obj);
  • 通过instanceof判断

    obj.instanceof Array
  • 通过Array.prototype.isPrototypeOf()判断

    Array.prototype.isPrototypeOf(obj)

typeof null的结果是什么,为什么?

typeof null的结果是Object。

在JavaScript第一个版本中,所有值都存储在32位的单元中,每个单元包含一个小的类型标签(1~3bits)以及当前要存储的真实数据。类型标签存储在每个单元的低位中,共有五种数据类型。

000:object  - 当前存储的数据指向一个对象
  1:int     - 当前存储的数据是一个31位的有符号整数
010:double  - 当前存储的数据指向一个双精度的浮点数
100:string  - 当前存储的数据指向一个字符串
110:boolen  - 当前存储的数据是布尔值

如果最低位是1,则类型标签标志位的长度只有一位;如果最低位是0,则类型标签标志位的长度占三位,为存储其他四种数据类型提供了额外两个bit的长度。

有两种特殊数据类型:

  • undefined的值是(-2)^30(一个超出整数范围的数字);

  • null的值是机器码NULL指针(null指针的值全是0)

也就是说null的类型标签也是000,和object的类型标签是一样的,所以会被判定为object。

为什么0.1+0.2!==0.3,如何让其相等

在开发过程中遇到类似这样的问题:

let n1 = 0.1, n2 = 0.2
console.log(n1+n2)//0.3000000000004

计算机是通过二进制的方式存储数据的,所以计算机计算0.1+0.2的时候,实际上是计算两个数的二进制的和。0.1的二进制是0.0001100110011001100......(1100循环),0.2的二进制是0.0011001100110011......(1100循环)这两个数的二进制都是无限循环的数,JavaScript中只有Number这一种数字类型,它的实现遵循IEEE 754标准,用64位固定长度来表示,且遵从“0舍1入”的原则。根据这个原则,0.1和0.2的二进制数相加,再转换为十进制数就是0.30000000000000004。

因此当我们想要得到想要的结果时,可以使用toFixed(num)方法,将Number四舍五入为指定小数位数的数字

(n1+n1).toFixed(2) //注意,toFixed为四舍五入

JS数组去重

方式一:new set

var arr1 = [1,2,3,2,4,1];
function unique(arr){
    return [...new Set(arr)]
}
console.log(  unique(arr1) );

方式二:indexOf

var arr2 = [1,2,3,2,4,1];
function unique( arr ){
    var brr = [];
    for( var i=0;i<arr.length;i++){
        if(  brr.indexOf(arr[i]) == -1 ){
            brr.push( arr[i] );
        }
    }
    return brr;
}
console.log( unique(arr2) );

方式三:sort

var arr3 = [1,2,3,2,4,1];
function unique( arr ){
    arr = arr.sort();
    var brr = [];
    for(var i=0;i<arr.length;i++){
        if( arr[i] !== arr[i-1]){
            brr.push( arr[i] );
        }
    }
    return brr;
}
console.log( unique(arr3) );

let、const、var的区别

(1)块级作用域:块级作用域由{ }包括,let和const具有块级作用域,var不存在块级作用域。块级作用域解决了ES5中内层变量可能覆盖外层变量、用来计数的循环变量泄露为全局变量两个问题。

(2)变量提升:var存在变量提升,let和const不存在变量提升,即变量只能在声明之后使用,否则会报错。

(3)给全局添加属性:浏览器的全局对象是window,Node的全局对象是global。var声明的变量为全局变量,并且会将该变量添加为全局对象的属性,但是let和const不会。

(4)重复声明:var声明变量时,可以重复声明变量,后声明的同名变量会覆盖之前声明的变量。const和let不允许重复声明变量。

(5)暂时性死区:在使用let、const声明变量之前,该变量都是不可用的。这在语法上,称为暂时性死区。使用var声明的变量不存在暂时性死区。

(6)初始值设置:在变量声明时,var和let可以不用设置初始值。而const声明变量必须设置初始值。

后入先出

在js中,我们可以通过push()方法和pop()方法对一个数组进行操作,实现入栈和出栈。

push()方法,是将某一元素添加到数组的末尾位置,而pop()方法,是将数组的最后一个元素删除并将被删除的元素返回。

队列

先进先出

同上,我们可以通过push()方法和shift()方法对数组进行操作,实现入队和出队

shift()方法,将数组的第一个元素删除

链表

什么是链表

(1)多个元素存储的列表

(2)链表中的元素在内存中不是顺序存储的,而是通过" next'指针联系在起的。

js中的原型链原理就是链表结构

链表和数组的区别

(1)数组:有序存储的,在中间某个位置删除或者添加某个元素,其他元素要跟着动。

(2)链表中的元素在内存中不是顺序存储的,而是通过" next"指针联系在一起的。

(3)数组如果在中间插入新的元素,其他元素会重新计算,链表不会重新计算。

(4)查找时,数组通过下标进行查找,链表每次查找都需要从头开始找。

字典

创建map文章来源地址https://www.toymoban.com/news/detail-402076.html

let map = new Map();
map.set('a','1');
map.set('b','2');
console.log(map.get('b'));获取并打印b
map.delete('a')
map.size    读取map的个数,相当于数组的length
map.clear()   将map中的数全删了

二叉树

结构

const tree = {
    val:'1',
    left:{
        val:'2',
        left:{val:'4',left:null,right:null},
        right:{val:'5',left:null,right:null}
    }
    right:{
        val:'3',
        left:{val:'6',left:null,right:null},
        right:{val:'7',left:null,right:null}
    }
}

二叉树前序遍历

var preorderTraversal = function(root) {
    let arr = [];
    var fun = ( node ) => {
        if( node ){
            arr.push(node.val);
            fun(node.left);
            fun(node.right);
        }
    }
    fun(root);
    return arr;
};

前序遍历 栈版本  非递归版本

var preorderTraversal = function(root) {
    if(!root) return [];
    let arr = [];
    //根节点入栈
    let stack = [root];
    while(stack.length){
        //出栈
        let o = stack.pop();
        arr.push(o.val);
        o.right && stack.push(o.right);
        o.left && stack.push(o.left);
    }
    return arr;
};

二叉树中序遍历

var inorderTraversal = function(root) {
    let arr = [];
    var fun = ( root ) => {
        if( !root ) return;
        fun(root.left);
        arr.push(root.val);
        fun(root.right);
    }
    fun(root);
    return arr;
};

中序遍历 栈版本  非递归版本

var inorderTraversal = function(root) {
    const arr = [];
    const stack = [] ;
    let o = root ;
    while( stack.length || o ){
        while(o){
            stack.push(o);
            o=o.left;
        }
        const n = stack.pop() ;
        arr.push( n.val ) ;
        o = n.right ;
    }
    return arr;
};

后序遍历

var postorderTraversal = function(root) {
const arr = [];
const fun = (node)=>{
    if(node){
        fun(node.left);
        fun(node.right);
        arr.push(node.val)
    }
}
fun(root);
    return arr;
};

后序遍历 栈版本  非递归版本

var postorderTraversal = function(root) {
    let arr = [];
    let stack = [root];
    while(stack.length){
        const o = stack.pop();
        arr.unshift(o.val);
        o.left && stack.push(o.left);
        o.right && stack.push(o.right);
    }
    return arr;
};

到了这里,关于JavaScript面经的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • JavaScript面经

    目录 延迟加载js有哪些方式? 数据类型有哪些? null和undefined的区别 数据类型检测的方式有哪些? (1)typeof (2)instanceof (3)constructor (4)Object.prototype.toString.call() 判断数组的方式有哪些 通过Object.prototype.toString.call()做判断 通过原型链做判断 通过ES6的Array.isArray()做判断 通

    2023年04月08日
    浏览(31)
  • arcgis javascript api4.x以basetilelayer方式加载天地图web墨卡托(wkid:3857)坐标系

    arcgis javascript api4.x以basetilelayer方式加载天地图web墨卡托(wkid:3857)坐标系 提示: 2个文件放同一个文件夹下 MyCustomTileLayer.js loadtdt3857.html https://www.cnblogs.com/hjyjack9563-bk/p/16067633.html

    2024年01月19日
    浏览(52)
  • 如何从 Keras 中的深度学习目录加载大型数据集

            数据集读取,使用、 在磁盘上存储和构建图像数据集有一些约定,以便在训练和评估深度学习模型时能够快速高效地加载。本文介绍Keras 深度学习库中的 ImageDataGenerator 类等工具自动加载训练、测试和验证数据集。         您可以使用Keras 深度学习库中的 Im

    2024年02月02日
    浏览(47)
  • mybatis分页、延迟加载、立即加载、一级缓存、二级缓存

    分类 : 使用Limit,来进行分页;物理分页 使用RowBounds集合来保存分页需要数据,来进行分页;逻辑分页;本质是全查,只是显示部分 使用分页插件来进行分页;物理分页 方式一: 方式二: 方式三: 首先导入两个jar包: 配置插件: 调用: 字段 含义 pageNum 当前页的页码 pa

    2024年01月18日
    浏览(56)
  • Mybatis延迟加载(缓存)

    分步查询的优点:可以实现延迟加载,但是必须在核心配置文件中设置全局配置信息: lazyLoadingEnabled:延迟加载的全局开关。当开启时,所有关联对象都会延迟加载 aggressiveLazyLoading:当开启时,任何方法的调用都会加载该对象的所有属性。 否则,每个属性会按需加载 此时就

    2024年02月07日
    浏览(40)
  • 面试题速记:JavaScript有哪些数据类型,它们的区别是?

    JavaScript有哪些数据类型,它们的区别? JavaScript共有八种数据类型,分别是 Undefined、Null、Boolean、Number、String、Object、Symbol、BigInt。 其中 Symbol 和 BigInt 是ES6 中新增的数据类型: ●Symbol 代表创建后独一无二且不可变的数据类型,它主要是为了解决可能出现的全局变量冲突的

    2024年02月09日
    浏览(43)
  • 大数据存储方式有哪些?

    本文隶属于专栏《大数据从 0 到 1》,该专栏为笔者原创,引用请注明来源,不足和错误之处请在评论区帮忙指出,谢谢! 本专栏目录结构和文献引用请见《大数据从 0 到 1》 数据常用的存储介质为磁盘和磁带。 数据存储组织方式因存储介质不同而异。 在磁带上数据仅按顺

    2024年02月07日
    浏览(39)
  • 什么是数据脱敏,数据脱敏有哪些方式

            数据脱敏又称数据去隐私化或数据变形,是在给定的规则、策略下对敏感数据进行变换、修改的技术机制,能够在很大程度上解决敏感数据在非可信环境中使用的问题。 静态脱敏 静态脱敏是指对敏感数据进行脱敏处理后,将数据从生产环境导入到其他非生产环境

    2024年02月11日
    浏览(53)
  • 【MyBaits】4、延迟加载、MyBatis 的缓存

    🍃 关联对象( association 、 collection )可以实现延迟加载 🍃 实现延迟加载需设置如下属性 fetchType :设置为 lazy select :指定一个 select 标签的 id(用于查询需要延迟加载的记录) column :指定一个列的值(作为 select 查询时传入的参数值) 🍃 一般会给 collection 设置延迟加载

    2024年02月09日
    浏览(40)
  • 【前端面经】Vue-Vue Router 路由有哪些模式?各模式有什么区别?

    Vue Router 是一个轻量级的前端路由库,它提供了三种路由模式,每种模式都适用于不同的场景。本文将详细介绍这三种模式的优缺点和适用场景,以便读者在使用 Vue Router 时进行选择。 在 hash 模式下,URL 中的 hash 值作为路由路径。该模式可以兼容较老的浏览器,并且无需后端

    2024年02月03日
    浏览(41)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包