JavaScript面试题看这一篇就够了,简单全面一发入魂(持续更新 step1)

2023-11-07

目录

1、BOM、DOM有什么区别?

(1)DOM

文档对象模型(DOM,Document Object Model)是一个应用编程接口(API),用于在HTML中使用扩展的HTML。DOM将整个页面抽象为一组分层节点。
DOM通过创建表示文档的树,让开发者可以随心所欲的控制网页的内容和结构。使用DOM API可以轻松地删除、添加、替换、修改节点。
对浏览器而言,DOM就是使用ECMAScript实现的,如今已经成为JavaScript语言的一大组成部分。
言而言之,DOM提供与网页内容交互的方法和接口。

(2)BOM

IE3和Netscape Navigator3提供了浏览器对象模型(BOM)API,用于支持访问和操作浏览器的窗口。使用BOM,开发者可以操控浏览器显示页面之外的部分。
BOM的能力展示:

  1. 弹出新浏览器窗口的能力;
  2. 移动、缩放和关闭浏览器窗口的能力;
  3. navigator对象,提供关于浏览器的详尽信息;
  4. location对象,提供浏览器加载页面的详尽信息;
  5. screen对象,提供关于用户屏幕分辨率的详尽信息;
  6. performance对象,提供浏览器内存占用、导航行为和时间统计的详尽信息;
  7. 对cookie的支持;
  8. 其它自定义对象,如XMLHttpRequest和IE的ActiveXObject。
    简而言之,BOM提供与浏览器交互的方法和接口。

2、JavaScript中代码后加不加分号;有什么区别?

  1. 加分号有助于防止省略造成的问题
  2. 避免输入内容不完整
  3. 便于开发者通过删除空行来压缩代码(如果没有结尾的分号,只删除空行,则会导致语法错误)
  4. 加分号有助于提升性性能,因为解析器会尝试在合适的位置补上分号以纠正语法错误。

3、var与let、const有什么区别?

  1. let不具备声明提升,var具备声明提升
  2. let声明的范围是块作用域,而var声明的范围是函数作用域。
  3. let是ES6才引入的声明关键字
  4. for循环中的let声明
  5. const与let很相似,最大的区别是const必须初始化,且不能再次赋值。

结语:

  1. 不使用var,有了let和const,大多数开发者会发现自己不再需要var了,限制自己只使用let和const,有助于提升代码质量,因为变量有了明确的作用域、声明位置、以及不变的值。
  2. const优先,let次之。使用const声明可以让浏览器运行时强制保持变量不变,也可以让静态代码分析工具提前发现不合法的赋值操作。

4、原始值和引用值有什么区别?

  1. 原始值大小固定,保存在栈内存中
  2. 从一个变量到另一个变量复制原始值,会创建该值得第二个副本
  3. 引用值是对象,存储在堆内存中
  4. 包含引用值的变量实际上只包含指向相应对象的一个指针,而不是对象本身
  5. 从一个变量到另一个变量复制引用值,只会复制指针,因此结果是两个变量都指向同一个对象
  6. typeof操作费可以确定值的原始类型,instanceof操作符用于确保值得引用类型

5、什么是执行上下文?

任何变量都存在于某个执行上下文中(也称为作用域)。这个上下文(作用域)决定了变量的生命周期,以及它们可以访问代码的哪些部分。
执行上下文可以总结如下:

  1. 执行上下文分为 ① 全局上下文、② 函数上下文、③ 块级上下文
  2. 代码执行流每进入一个新上下文,都会创建一个作用域链,用于搜索变量和函数
  3. 函数或块的局部上下文不仅可以访问自己作用域内的变量,也可以访问任何包含上下文乃至全局上下文的变量
  4. 全局上下文只能访问全局上下文中的变量和函数,不能直接访问局部上下文中的任何数据
  5. 变量的执行上下文用于确定什么时候释放内存

6、解释一下JavaScript垃圾回收?

JavaScript是使用垃圾回收的编程语言,开发者不需要操心内存分配和回收。

  1. 离开作用域的值会被自动标记为可回收,然后在垃圾回收期间被删除
  2. 主流的垃圾回收算法是标记算法,即先给当前不使用的值加上标记,再回来回收它们的内存
  3. 引用计数是另一种垃圾回收策略,需要记录值被引用了多少次。JavaScript引擎不再使用这种算法,但某些旧版本的IE仍然会受这种算法的影响,原因是JavaScript会访问非原生JavaScript对象(如DOM对象)。
  4. 引用计数在代码中循环引用时会出现问题
  5. 解除变量的引用不仅可以消除循环引用,而且对垃圾回收也有帮助。为促进内存回收,全局对象、全局对象的属性和循环引用都应该在不需要时解除引用。

7、如何判断一个对象是不是数组?

在只有一个全局作用域的时候,使用instanceof操作符就足矣:

if(value instanceof Array){
	//操作数组
}

使用instanceof的前提是只有一个全局执行上下文,如果网页里有多个框架,则可能涉及两个不同的全局上下文,因此就会有两个不同版本的Array构造函数。如果要把数组从一个框架传到另一个框架,则这个数组的构造函数将有别于第二个框架内本地创建的数组。
为了解决这个问题,ECMAScript提供了 Array.isArray()方法。这个方法的目的就是确定一个值是否为数组,而不用管它是在哪个全局执行上下文中创建的。

if(Array.isArray(value)){
	//操作数组
}

8、Object和Map到底有什么区别?

(1)内存占用

给定固定大小内存的情况下,Map一般会比Object多存储50%的键值对。

(2)插入性能

插入Map一般会稍微快一点。

(3)查找速度

相差无几。

(4)删除性能

Map的删除性能完胜Object。
综上四点,选择Map显然是更好地选择。

9、简述一下什么是Set?

(1)基础API

  1. 添加add()
  2. 查询has()
  3. 获取数量size
  4. 删除delete()
  5. 清空clear()

(2)顺序与迭代

Set会维护值插入时的顺序,因此支持按顺序迭代。
集合实例可以提供一个迭代器Iterator,能以插入顺序生成集合内容。可以通过values()方法及其别名方法keys(),或者Symbol.iterator属性,他引用values(),取得这个迭代器。

const s = new Set("哪吒","云韵","比比东");

alert(s.keys === s[Symbol.iterator]);//true
alert(s.values === s[Symbol.iterator]);//true

for(let value of s.values()){

}

for(let value of s[Symbol.iterator]){

}

因为values()是默认迭代器,所以可以直接对集合实例使用扩展操作,把集合转为数组:

const s = new Set("哪吒","云韵","比比东");
console.log([...s]);//["哪吒","云韵","比比东"]

10、什么是迭代器?

迭代器是一个可以由任意对象实现的接口,支持连续获取对象产出的每一个值。任何实现Iterable接口的对象都有一个Symbol.iterator属性,这个属性引用默认迭代器。默认迭代器就像一个迭代器工厂,也就是一个函数,调用之后会产生一个实现Iterator接口的对象。
迭代器必须通过连续调用next()方法才能连续获取值,这个方法返回一个IteratorObject。这个对象包含一个done属性和一个value属性。前者时刻一个布尔值,表示十分还有更多值可以访问;后者包含迭代器返回的当前值。这个接口可以通过手动反复调用next()方法来消费,也可以通过原生消费者,比如for循环来自动消费。

11、什么是生成器?

生成器是ECMAScript6新增的一个极为灵活的结构,拥有在一个函数块内暂停和恢复代码执行的能力。这种新能力具有较深远的影响,比如,使用生成器可以自定义迭代器和实现协程。
生成器的形式是一个函数,函数名称前面加一个星号*,表示它是一个生成器。只要是可以定义函数的地方,就可以定义生成器。
调用生成器函数会产生一个生成器对象,生成器对象一开始处于暂停执行(suspended)状态。与迭代器相似,生成器对象也实现了Iterator接口,因此具有next()方法。调用这个方法会让生成器开始或恢复执行。
next()方法的返回值类似于迭代器,有一个done属性和一个value属性。函数体为空的生成器函数中间不会停留,调用一次next()就会让生成器到达done:true状态。

12、JavaScript的继承是通过什么方式实现的?(问法2:什么是原型链?问法3:构造函数、原型、实例三者的关系?)

ECMA-262把原型链定义为ECMAScript的主要继承方式。其基本思想就是通过原型继承多个引用类型的属性和方法。
每个构造函数都有一个原型对象,原型有一个属性指回构造函数,而实例有一个内部指针指向原型。如果原型是另一个类型的实例呢?那就意味着这个原型本身有一个内部指针指向另一个原型,相应地另一个原型也有一个指针指向另一个构造函数,这样就在实例和原型之间构造了一条原型链。

13、以下表达式,对吗?为什么?

console.log(sum(1,2));
function sum(num1,num2){
    return num1+num2;
}

JavaScript引擎在任何代码执行之前,会先读取函数声明,并在执行上下文中生成函数定义。而函数表达式必须等到代码执行到它那一行,才会在执行上下文中生成函数定义。
所以,以上代码是可以正常运行的,因为函数声明会在任何代码执行之前先被读取并添加到执行上下文,这个过程叫做函数声明提升。
在执行代码时,JavaScript引擎会先执行一遍扫描,把发现的函数声明提升到源代码树的顶部。因此即使函数定义出现在它们的代码之后,引擎也会把函数声明提升到顶部。
如果把前面代码中的函数声明改为等价的函数表达式,那么执行的时候就会出错。

console.log(sum(1,2));
let sum = function sum(num1,num2){
    return num1+num2;
}

14、apply()和call()有什么区别?

这两个方法都会以制定的this值来调用函数,即会设置调用函数时函数体内的this对象的值。
apply()接收两个参数,函数体this的值和一个参数数组。第二个对象是Array的实例,也可以是arguments对象。
call()和apply()的作用是一样的,只是传入参数的形式不一样。call()传入的不是数组或arguments对象,而是将参数一个一个的传入。
apply()和call()真正的用处不在于传递参数,而在于控制this。

  window.color = 'red';
  let o = {
    color:'blue';
  }
  
  function getColor(){
    console.log(this.color);
  }
  
  getColor(); //red
  getColor().call(this);//red
  getColor().call(window);//red
  getColor().call(o);//blue

15、函数声明和函数表达式有什么区别?

函数声明是这样的:

  function functionNam(arg0,arg1,arg2){
    //函数体
  }

函数式声明的关键特点是函数声明提升,即函数声明会在代码执行前获得定义。
函数表达式是什么?

  let functionName = function(arg0.arg1,arg2){
    //函数体
  }

函数表达式看起来就像一个普通的变量定义和赋值,即创建一个函数再把它赋值给一个变量functionName。这样创建的函数叫做匿名函数,因为function关键字后面没有标识符。匿名函数有时也被成为兰姆达函数。
函数表达式和其他表达式一样,需要先赋值再使用,所以如下代码就是错误的。

  sayHello();
  let sayHello = function(){
    console.log("hello world");
  }

函数声明和函数表达式的根本区别在于理解提升。

16、关注公众号哪吒编程,回复1024,获取Java学习资料,还有不定期的送书活动

  1. 极简Java
  2. Node+MongoDB+React 项目实战开发
  3. 微信小程序开发从入门到实战
  4. C++从入门到精通

在这里插入图片描述

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

JavaScript面试题看这一篇就够了,简单全面一发入魂(持续更新 step1) 的相关文章

  • 从 Android 访问云存储

    我一直无法找到任何有关如何从 Android 应用程序使用云存储的具体文档 我确实遇到过这个客户端库 https cloud google com storage docs reference libraries然而 Google Clou
  • 合并两个地图的最佳实践是什么

    如何将新地图添加到现有地图 地图具有相同的类型Map
  • 为什么这个递归函数返回未定义?

    我正在尝试编写一个使用递归组合两个字符串的函数 我的代码如下 但我不知道为什么该函数返回未定义 特别是当我在基本情况下使用 console log 时 它不会打印未定义而是打印正确的值 var str3 function merge str
  • 如何将React JS状态保存到本地存储中

    我不知道如何将 React js 状态存储到本地存储中 import React Component from react import App css import auth createUserProfileDocument from
  • 使用 eval 时不会受到 XSS 威胁

    我正在制作 不是现在 但我仍然对这个感到好奇 一款使用 HTML5 和 JS 的游戏 我想要的是人们可以插入自定义脚本 但要安全 function executeCustomJS code eval code bad 当然这段代码非常糟糕
  • Java8:流映射同一流中的两个属性

    我有课Model带有以下签名 class Model private String stringA private String stringB public Model String stringA String stringB this
  • 如何检查日期字符串的有效性?

    在我的项目中 我需要检查日期字符串是否计算为正确的日期对象 我决定允许 yyyy MM dd 和日期格式 年 月 日 和 年 月 日 小时 分钟 我如何检查它们是否有效 我的代码为 1980 01 01 和一些奇怪的日期 如 3837 05
  • Java 中处理异步响应的设计模式

    我读过类似问答的答案 如何在 JAVA 中创建异步 HTTP 请求 https stackoverflow com questions 3142915 how do you create an asynchronous http reque
  • Java String ReplaceAll 方法给出非法重复错误?

    我有一个字符串 当我尝试运行时replaceAll方法 我收到这个奇怪的错误 String str something op str str replaceAll o n it works fine str str replaceAll n
  • 为什么 TypeScript 混合了模块和原型模式?

    我正在查看此页面上 TypeScript 生成的 JS 代码 http www typescriptlang org Playground http www typescriptlang org Playground 基本上 要创建一个Gr
  • 在 Freemarker 模板中检查 Spring 安全角色和记录的用户名

    有谁知道 freemarker 标签来检查 freemarker 文件中的 spring 安全角色和用户名 我从网络上的几个资源中发现以下代码将打印登录的用户名 但它没有打印用户名 而是打印 登录为
  • 如何禁用网页中的萤火虫?

    如何使用 Javascript 禁用 firebug 我想这样做是为了向访问者隐藏我的网页的运作方式 有什么选择可以做到这一点吗 你不能 你能做的最好的事情就是混淆你的 JavaScript 实际上刮掉了 您能做的最好的事情就是将所有安全关
  • CXF:通过 SOAP 发送对象时如何排除某些属性?

    我使用 Apache CXF 2 4 2 当我将数据库中的某个对象返回给用户时 我想排除一些属性 例如密码 我怎样才能做到这一点无需创建临时的班级 有这方面的注释吗 根据 tomasz nurkiewicz 评论我应该使用 XmlTrans
  • Java 中的微分方程

    我正在尝试用java创建一个简单的SIR流行病模型模拟程序 基本上 SIR 由三个微分方程组定义 S t l t S t I t l t S t g t I t R t g t I t S 易感人群 I 感染人群 R 康复人群 l t c
  • 为什么我不能将 Collection 转换为 Collection>

    问题的关键是 为什么这会导致编译时错误 List
  • 测试 jQueryUI 是否已加载

    我正在尝试调试网站 并且我认为 jQueryUI 可能未正确加载 如何测试 jQueryUI 是否已加载 if jQuery ui UI loaded OR if typeof jQuery ui undefined UI loaded 应
  • 使用自定义比较器在 Java 中创建 SortedMap

    我想创建一个TreeMap在 Java 中具有自定义排序顺序 排序后的键是字符串 需要根据第二个字符进行排序 这些值也是字符串 示例地图 Za FOO Ab Bar 您可以像这样使用自定义比较器 Comparator
  • Android Google 地图无法在当前主题中找到样式“mapViewStyle”

    添加谷歌地图视图时 我扩展了MapView 使用xml编辑器将其添加到活动中 并将我的谷歌地图api密钥手动添加到布局xml文件中 我的权限在清单文件中允许互联网 我想知道的是 在 xml 编辑器中 我收到错误 无法在当前主题中找到样式 m
  • 突出显示单词并提取其附近文本的函数

    我有一个文本例如 Etiam porta semmalesuada magna mollis euismod 整数取数 ante venenatis dapibus posuere velit aliquet 埃蒂亚姆 门塔 塞姆 male
  • 拉斐尔路径交叉点不起作用

    我对拉斐尔和 pathIntersection method JSFiddle 示例 http jsfiddle net t6gWt 2 您可以看到有两条线都与曲线相交 但当我使用 pathIntersection method 有一个未解

随机推荐