100道JavaScript题

... 2025-7-10 JavaScript 大约 22 分钟

本文来自100 道 JavaScript 面试题,助你查漏补缺 (opens new window)

大佬博客:CavsZhouyou's Blog (opens new window)

# 介绍 js 的基本数据类型

js 一共有六种基本数据类型,分别是 Undefined、Null、Boolean、Number、String,还有在 ES6 中新增的 Symbol 类型, 代表创建后独一无二且不可变的数据类型,它的出现我认为主要是为了解决可能出现的全局变量冲突的问题。

少了BigInt

# JavaScript 有几种类型的值?你能画一下他们的内存图吗?

涉及知识点:

  • 栈:原始数据类型(Undefined、Null、Boolean、Number、String)
  • 堆:引用数据类型(对象、数组和函数)

两种类型的区别是:存储位置不同。 原始数据类型直接存储在栈(stack)中的简单数据段,占据空间小、大小固定,属于被频繁使用数据,所以放入栈中存储。

引用数据类型存储在堆(heap)中的对象,占据空间大、大小不固定。如果存储在栈中,将会影响程序运行的性能;引用数据类型在 栈中存储了指针,该指针指向堆中该实体的起始地址。当解释器寻找引用值时,会首先检索其在栈中的地址,取得地址后从堆中获得实 体。

回答:

js 可以分为两种类型的值,一种是基本数据类型,一种是复杂数据类型。

基本数据类型....(参考 1)

复杂数据类型指的是 Object 类型,所有其他的如 Array、Date 等数据类型都可以理解为 Object 类型的子类。

两种类型间的主要区别是它们的存储位置不同,基本数据类型的值直接保存在栈中,而复杂数据类型的值保存在堆中,通过使用在栈中 保存对应的指针来获取堆中的值。

# 什么是堆?什么是栈?它们之间有什么区别和联系?

堆和栈的概念存在于数据结构中和操作系统内存中。

在数据结构中,栈中数据的存取方式为先进后出。而堆是一个优先队列,是按优先级来进行排序的,优先级可以按照大小来规定。完全 二叉树是堆的一种实现方式。

在操作系统中,内存被分为栈区和堆区。

栈区内存由编译器自动分配释放,存放函数的参数值,局部变量的值等。其操作方式类似于数据结构中的栈。

堆区内存一般由程序员分配释放,若程序员不释放,程序结束时可能由垃圾回收机制回收。

# 内部属性 [[Class]] 是什么?

所有 typeof 返回值为 "object" 的对象(如数组)都包含一个内部属性 [[Class]](我们可以把它看作一个内部的分类,而非 传统的面向对象意义上的类)。这个属性无法直接访问,一般通过 Object.prototype.toString(..) 来查看。例如:

Object.prototype.toString.call([1, 2, 3])
// "[object Array]"

Object.prototype.toString.call(/regex-literal/i)
// "[object RegExp]"
1
2
3
4
5

# 介绍 js 有哪些内置对象?

涉及知识点:

全局的对象( global objects )或称标准内置对象,不要和 "全局对象(global object)" 混淆。这里说的全局的对象是说在 全局作用域里的对象。全局作用域中的其他对象可以由用户的脚本创建或由宿主程序提供。

标准内置对象的分类

  • 值属性,这些全局属性返回一个简单值,这些值没有自己的属性和方法。

    例如 Infinity、NaN、undefined、null 字面量

  • 函数属性,全局函数可以直接调用,不需要在调用时指定所属对象,执行结束后会将结果直接返回给调用者。

    例如 eval()、parseFloat()、parseInt() 等

  • 基本对象,基本对象是定义或使用其他对象的基础。基本对象包括一般对象、函数对象和错误对象。

    例如 Object、Function、Boolean、Symbol、Error 等

  • 数字和日期对象,用来表示数字、日期和执行数学计算的对象。

    例如 Number、Math、Date

  • 字符串,用来表示和操作字符串的对象。

    例如 String、RegExp

  • 可索引的集合对象,这些对象表示按照索引值来排序的数据集合,包括数组和类型数组,以及类数组结构的对象。

    例如 Array

  • 使用键的集合对象,这些集合对象在存储数据时会使用到键,支持按照插入顺序来迭代元素。

    例如 Map、Set、WeakMap、WeakSet

  • 矢量集合,SIMD 矢量集合中的数据会被组织为一个数据序列。

    例如 SIMD 等

  • 结构化数据,这些对象用来表示和操作结构化的缓冲区数据,或使用 JSON 编码的数据。

    例如 JSON 等

  • 控制抽象对象

    例如 Promise、Generator 等

  • 反射

    例如 Reflect、Proxy

  • 国际化,为了支持多语言处理而加入 ECMAScript 的对象。

    例如 Intl、Intl.Collator 等

  • WebAssembly

  • 其他

    例如 arguments

回答:

js 中的内置对象主要指的是在程序执行前存在全局作用域里的由 js 定义的一些全局值属性、函数和用来实例化其他对象的构造函 数对象。一般我们经常用到的如全局变量值 NaN、undefined,全局函数如 parseInt()、parseFloat() 用来实例化对象的构 造函数如 Date、Object 等,还有提供数学计算的单体内置对象如 Math 对象。

# undefined 与 undeclared 的区别?

首先 Undefined 和 Null 都是基本数据类型,这两个基本数据类型分别都只有一个值,就是 undefined 和 null。

undefined 代表的含义是未定义,null 代表的含义是空对象。一般变量声明了但还没有定义的时候会返回 undefined,null 主要用于赋值给一些可能会返回对象的变量,作为初始化。

undefined 在 js 中不是一个保留字,这意味着我们可以使用 undefined 来作为一个变量名,这样的做法是非常危险的,它 会影响我们对 undefined 值的判断。但是我们可以通过一些方法获得安全的 undefined 值,比如说 void 0。

当我们对两种类型使用 typeof 进行判断的时候,Null 类型化会返回 “object”,这是一个历史遗留的问题。当我们使用双等 号对两种类型的值进行比较时会返回 true,使用三个等号时会返回 false。

# 如何获取安全的 undefined 值?

因为 undefined 是一个标识符,所以可以被当作变量来使用和赋值,但是这样会影响 undefined 的正常判断。

表达式 void ___ 没有返回值,因此返回结果是 undefined。void 并不改变表达式的结果,只是让表达式不返回值。

按惯例我们用 void 0 来获得 undefined。

# 说几条写 JavaScript 的基本规范?

在平常项目开发中,我们遵守一些这样的基本规范,比如说:

(1)一个函数作用域中所有的变量声明应该尽量提到函数首部,用一个 var 声明,不允许出现两个连续的 var 声明,声明时 如果变量没有值,应该给该变量赋值对应类型的初始值,便于他人阅读代码时,能够一目了然的知道变量对应的类型值。

(2)代码中出现地址、时间等字符串时需要使用常量代替。

(3)在进行比较的时候吧,尽量使用'===', '!=='代替'==', '!='。

(4)不要在内置对象的原型上添加方法,如 Array, Date。

(5)switch 语句必须带有 default 分支。

(6)for 循环必须使用大括号。

(7)if 语句必须使用大括号。

# JavaScript 原型,原型链? 有什么特点?

在 js 中我们是使用构造函数来新建一个对象的,每一个构造函数的内部都有一个 prototype 属性值,这个属性值是一个对 象,这个对象包含了可以由该构造函数的所有实例共享的属性和方法。当我们使用构造函数新建一个对象后,在这个对象的内部 将包含一个指针,这个指针指向构造函数的 prototype 属性对应的值,在 ES5 中这个指针被称为对象的原型。一般来说我们 是不应该能够获取到这个值的,但是现在浏览器中都实现了 __proto__ 属性来让我们访问这个属性,但是我们最好不要使用这 个属性,因为它不是规范中规定的。ES5 中新增了一个 Object.getPrototypeOf() 方法,我们可以通过这个方法来获取对 象的原型。

当我们访问一个对象的属性时,如果这个对象内部不存在这个属性,那么它就会去它的原型对象里找这个属性,这个原型对象又 会有自己的原型,于是就这样一直找下去,也就是原型链的概念。原型链的尽头一般来说都是 Object.prototype 所以这就 是我们新建的对象为什么能够使用 toString() 等方法的原因。

特点:

JavaScript 对象是通过引用来传递的,我们创建的每个新对象实体中并没有一份属于自己的原型副本。当我们修改原型时,与 之相关的对象也会继承这一改变。

# js 获取原型的方法?

  • p.proto
  • p.constructor.prototype
  • Object.getPrototypeOf(p)

# 在 js 中不同进制数字的表示方式

  • 以 0X、0x 开头的表示为十六进制。

  • 以 0、0O、0o 开头的表示为八进制。

  • 以 0B、0b 开头的表示为二进制格式。

# js 中整数的安全范围是多少?

安全整数指的是,在这个范围内的整数转化为二进制存储的时候不会出现精度丢失,能够被“安全”呈现的最大整数是2^53 - 1, 即 9007199254740991,在 ES6 中被定义为 Number.MAX_SAFE_INTEGER。最小整数是-9007199254740991,在 ES6 中 被定义为 Number.MIN_SAFE_INTEGER

如果某次计算的结果得到了一个超过 JavaScript 数值范围的值,那么这个值会被自动转换为特殊的 Infinity 值。如果某次 计算返回了正或负的 Infinity 值,那么该值将无法参与下一次的计算。判断一个数是不是有穷的,可以使用 isFinite 函数 来判断。

# typeof NaN 的结果是什么?

NaN 意指“不是一个数字”(not a number),NaN 是一个“警戒值”(sentinel value,有特殊用途的常规值),用于指出 数字类型中的错误情况,即“执行数学运算没有成功,这是失败后返回的结果”。

typeof NaN // "number"
1

NaN 是一个特殊值,它和自身不相等,是唯一一个非自反(自反,reflexive,即 x === x 不成立)的值。而 NaN != NaN 为 true。

# isNaN 和 Number.isNaN 函数的区别?

函数 isNaN 接收参数后,会尝试将这个参数转换为数值,任何不能被转换为数值的的值都会返回 true,因此非数字值传入也会 返回 true ,会影响 NaN 的判断。

函数 Number.isNaN 会首先判断传入参数是否为数字,如果是数字再继续判断是否为 NaN ,这种方法对于 NaN 的判断更为 准确。

# Array 构造函数只有一个参数值时的表现?

Array 构造函数只带一个数字参数的时候,该参数会被作为数组的预设长度(length),而非只充当数组中的一个元素。这样 创建出来的只是一个空数组,只不过它的 length 属性被设置成了指定的值。

构造函数 Array(..) 不要求必须带 new 关键字。不带时,它会被自动补上。

# 其他值到字符串的转换规则?

规范的 9.8 节中定义了抽象操作 ToString ,它负责处理非字符串到字符串的强制类型转换。

(1)Null 和 Undefined 类型 ,null 转换为 "null",undefined 转换为 "undefined",

(2)Boolean 类型,true 转换为 "true",false 转换为 "false"。

(3)Number 类型的值直接转换,不过那些极小和极大的数字会使用指数形式。

(4)Symbol 类型的值直接转换,但是只允许显式强制类型转换,使用隐式强制类型转换会产生错误。

(5)对普通对象来说,除非自行定义 toString() 方法,否则会调用 toString()(Object.prototype.toString()) 来返回内部属性 [[Class]] 的值,如"[object Object]"。如果对象有自己的 toString() 方法,字符串化时就会 调用该方法并使用其返回值。

# 其他值到数字值的转换规则?

有时我们需要将非数字值当作数字来使用,比如数学运算。为此 ES5 规范在 9.3 节定义了抽象操作 ToNumber。

(1)Undefined 类型的值转换为 NaN。

(2)Null 类型的值转换为 0。

(3)Boolean 类型的值,true 转换为 1,false 转换为 0。

(4)String 类型的值转换如同使用 Number() 函数进行转换,如果包含非数字值则转换为 NaN,空字符串为 0。

(5)Symbol 类型的值不能转换为数字,会报错。

(6)对象(包括数组)会首先被转换为相应的基本类型值,如果返回的是非数字的基本类型值,则再遵循以上规则将其强制转换为数字。

为了将值转换为相应的基本类型值,抽象操作 ToPrimitive 会首先(通过内部操作 DefaultValue)检查该值是否有 valueOf() 方法。如果有并且返回基本类型值,就使用该值进行强制类型转换。如果没有就使用 toString() 的返回值(如果存在)来进行强制类型转换。

如果 valueOf() 和 toString() 均不返回基本类型值,会产生 TypeError 错误。

# 其他值到布尔类型的值的转换规则?

ES5 规范 9.2 节中定义了抽象操作 ToBoolean,列举了布尔强制类型转换所有可能出现的结果。

以下这些是假值:

  • undefined
  • null
  • false
  • +0、-0 和 NaN
  • ""

假值的布尔强制类型转换结果为 false。从逻辑上说,假值列表以外的都应该是真值。

# {} 和 [] 的 valueOf 和 toString 的结果是什么?

{} 的 valueOf 结果为 {} ,toString 的结果为 "[object Object]"

[] 的 valueOf 结果为 [] ,toString 的结果为 ""

# 什么是假值对象?

浏览器在某些特定情况下,在常规 JavaScript 语法基础上自己创建了一些外来值,这些就是“假值对象”。假值对象看起来和 普通对象并无二致(都有属性,等等),但将它们强制类型转换为布尔值时结果为 false 最常见的例子是 document.all,它 是一个类数组对象,包含了页面上的所有元素,由 DOM(而不是 JavaScript 引擎)提供给 JavaScript 程序使用。

# ~ 操作符的作用?

~ 返回 2 的补码,并且 ~ 会将数字转换为 32 位整数,因此我们可以使用 ~ 来进行取整操作。

~x 大致等同于 -(x+1)。

# 解析字符串中的数字和将字符串强制类型转换为数字的返回结果都是数字,它们之间的区别是什么?

解析允许字符串(如 parseInt() )中含有非数字字符,解析按从左到右的顺序,如果遇到非数字字符就停止。而转换(如 Nu mber ())不允许出现非数字字符,否则会失败并返回 NaN。

# + 操作符什么时候用于字符串的拼接?

根据 ES5 规范 11.6.1 节,如果某个操作数是字符串或者能够通过以下步骤转换为字符串的话,+ 将进行拼接操作。如果其 中一个操作数是对象(包括数组),则首先对其调用 ToPrimitive 抽象操作,该抽象操作再调用 [[DefaultValue]],以 数字作为上下文。如果不能转换为字符串,则会将其转换为数字类型来进行计算。

简单来说就是,如果 + 的其中一个操作数是字符串(或者通过以上步骤最终得到字符串),则执行字符串拼接,否则执行数字 加法。

那么对于除了加法的运算符来说,只要其中一方是数字,那么另一方就会被转为数字。

# 什么情况下会发生布尔值的隐式强制类型转换?

(1) if (..) 语句中的条件判断表达式。

(2) for ( .. ; .. ; .. ) 语句中的条件判断表达式(第二个)。

(3) while (..) 和 do..while(..) 循环中的条件判断表达式。

(4) ? : 中的条件判断表达式。

(5) 逻辑运算符 ||(逻辑或)和 &&(逻辑与)左边的操作数(作为条件判断表达式)。

# || 和 && 操作符的返回值?

|| 和 && 首先会对第一个操作数执行条件判断,如果其不是布尔值就先进行 ToBoolean 强制类型转换,然后再执行条件 判断。

对于 || 来说,如果条件判断结果为 true 就返回第一个操作数的值,如果为 false 就返回第二个操作数的值。

&& 则相反,如果条件判断结果为 true 就返回第二个操作数的值,如果为 false 就返回第一个操作数的值。

|| 和 && 返回它们其中一个操作数的值,而非条件判断的结果

# Symbol 值的强制类型转换?

ES6 允许从符号到字符串的显式强制类型转换,然而隐式强制类型转换会产生错误。

Symbol 值不能够被强制类型转换为数字(显式和隐式都会产生错误),但可以被强制类型转换为布尔值(显式和隐式结果 都是 true )。

# == 操作符的强制类型转换规则?

(1)字符串和数字之间的相等比较,将字符串转换为数字之后再进行比较。

(2)其他类型和布尔类型之间的相等比较,先将布尔值转换为数字后,再应用其他规则进行比较。

(3)null 和 undefined 之间的相等比较,结果为真。其他值和它们进行比较都返回假值。

(4)对象和非对象之间的相等比较,对象先调用 ToPrimitive 抽象操作后,再进行比较。

(5)如果一个操作值为 NaN ,则相等比较返回 false( NaN 本身也不等于 NaN )。

(6)如果两个操作值都是对象,则比较它们是不是指向同一个对象。如果两个操作数都指向同一个对象,则相等操作符返回 true,否则,返回 false。

# 如何将字符串转化为数字,例如 '12.3b'?

(1)使用 Number() 方法,前提是所包含的字符串不包含不合法字符。

(2)使用 parseInt() 方法,parseInt() 函数可解析一个字符串,并返回一个整数。还可以设置要解析的数字的基数。当基数的值为 0,或没有设置该参数时,parseInt() 会根据 string 来判断数字的基数。

(3)使用 parseFloat() 方法,该函数解析一个字符串参数并返回一个浮点数。

(4)使用 + 操作符的隐式转换。

# 如何将浮点数点左边的数每三位添加一个逗号,如 12000000.11 转化为『12,000,000.11』?

function format(number) {
  return number && number.replace(/(?!^)(?=(\d{3})+\.)/g, ',')
}
1
2
3

# 常用正则表达式

// (1)匹配 16 进制颜色值
var regex = /#([0-9a-fA-F]{6}|[0-9a-fA-F]{3})/g

// (2)匹配日期,如 yyyy-mm-dd 格式
var regex = /^[0-9]{4}-(0[1-9]|1[0-2])-(0[1-9]|[12][0-9]|3[01])$/

// (3)匹配 qq 号
var regex = /^[1-9][0-9]{4,10}$/g

// (4)手机号码正则
var regex = /^1[34578]\d{9}$/g

// (5)用户名正则
var regex = /^[a-zA-Z\$][a-zA-Z0-9_\$]{4,16}$/
1
2
3
4
5
6
7
8
9
10
11
12
13
14

可以参考:前端表单验证常用的 15 个 JS 正则表达式 (opens new window)JS 常用正则汇总 (opens new window)

# 生成随机数的各种方法?

  • 生成 [ 0, 1 ) 范围内的随机数(大于等于 0,小于 1)
Math.random()
1
  • 生成 [ n, m ) 范围内的随机数(大于等于 n,小于 m)
Math.random() * (m - n) + n
1
  • 生成 [n,m]、(n,m)、(n,m] 范围内的随机数
//取得[n,m]范围随机数
function fullClose(n, m) {
  var result = Math.random() * (m + 1 - n) + n
  while (result > m) {
    result = Math.random() * (m + 1 - n) + n
  }
  return result
}
//取得(n,m)范围随机数
function fullOpen(n, m) {
  var result = Math.random() * (m - n) + n
  while (result == n) {
    result = Math.random() * (m - n) + n
  }
  return result
}
//取得(n,m]范围随机数
function leftOpen(n, m) {
  var result = Math.random() * (m - n + 1) + n - 1
  while (result < n) {
    result = Math.random() * (m - n + 1) + n - 1
  }
  return result
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
  • 随机生成 0、1 这两个整数
Math.round(Math.random())
1
  • 生成 [ 0, n ) 范围内的随机整数(大于等于 0,小于 n)
Math.floor(Math.random() * n)
1
  • 生成 [ 1, n ] 范围内的随机整数(大于等于 1,小于等于 n)
Math.floor(Math.random() * n) + 1
1
  • 生成 [ min, max ] 范围内的随机整数(大于等于 min,小于等于 max)
Math.floor(Math.random() * (max - min + 1)) + min
1
  • 生成指定位数的纯数字字符串
//生成n位数字字符串
function randomNum(n) {
  var res = ''
  for (var i = 0; i < n; i++) {
    res += Math.floor(Math.random() * 10)
  }
  return res
}
1
2
3
4
5
6
7
8
  • 生成指定位数的数字字母混合的字符串
function generateMixed(n) {
  var chars = [...] // 0-9,A-Z
  var res = ''
  for (var i = 0; i < n; i++) {
    var id = Math.floor(Math.random() * 36)
    res += chars[id]
  }
  return res
}
1
2
3
4
5
6
7
8
9

# 如何实现数组的随机排序?

// (1)使用数组 sort 方法对数组元素随机排序,让 Math.random() 出来的数与 0.5 比较,如果大于就返回 1 交换位置,如果小于就返回 -1,不交换位置。

function randomSort(a, b) {
  return Math.random() > 0.5 ? -1 : 1
}

//  缺点:每个元素被派到新数组的位置不是随机的,原因是 sort() 方法是依次比较的。

// (2)随机从原数组抽取一个元素,加入到新数组

function randomSort(arr) {
  var result = []

  while (arr.length > 0) {
    var randomIndex = Math.floor(Math.random() * arr.length)
    result.push(arr[randomIndex])
    arr.splice(randomIndex, 1)
  }

  return result
}

// (3)随机交换数组内的元素(洗牌算法类似)

function randomSort(arr) {
  var index,
    randomIndex,
    temp,
    len = arr.length

  for (index = 0; index < len; index++) {
    randomIndex = Math.floor(Math.random() * (len - index)) + index

    temp = arr[index]
    arr[index] = arr[randomIndex]
    arr[randomIndex] = temp
  }

  return arr
}

// es6
function randomSort(array) {
  let length = array.length

  if (!Array.isArray(array) || length <= 1) return

  for (let index = 0; index < length - 1; index++) {
    let randomIndex = Math.floor(Math.random() * (length - index)) + index

    ;[array[index], array[randomIndex]] = [array[randomIndex], array[index]]
  }

  return array
}
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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55

# javascript 创建对象的几种方式

参考: JavaScript 深入理解之对象创建 (opens new window)

# JavaScript 继承的几种实现方式?

参考: JavaScript 深入理解之继承 (opens new window)

# 寄生式组合继承的实现?

function Person(name) {
  this.name = name
}

Person.prototype.sayName = function () {
  console.log('My name is ' + this.name + '.')
}

function Student(name, grade) {
  Person.call(this, name)
  this.grade = grade
}

Student.prototype = Object.create(Person.prototype)
Student.prototype.constructor = Student

Student.prototype.sayMyGrade = function () {
  console.log('My grade is ' + this.grade + '.')
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

# Javascript 的作用域链?

作用域链的作用是保证对执行环境有权访问的所有变量和函数的有序访问,通过作用域链,我们可以访问到外层环境的变量和 函数。

作用域链的本质上是一个指向变量对象的指针列表。变量对象是一个包含了执行环境中所有变量和函数的对象。作用域链的前 端始终都是当前执行上下文的变量对象。全局执行上下文的变量对象(也就是全局对象)始终是作用域链的最后一个对象。

当我们查找一个变量时,如果当前执行环境中没有找到,我们可以沿着作用域链向后查找。

作用域链的创建过程跟执行上下文的建立有关....

参考: JavaScript 深入理解之作用域链 (opens new window)

# 谈谈 This 对象的理解。

this 是执行上下文中的一个属性,它指向最后一次调用这个方法的对象。在实际开发中,this 的指向可以通过四种调用模 式来判断。

  • 第一种是函数调用模式,当一个函数不是一个对象的属性时,直接作为函数来调用时,this 指向全局对象。

  • 第二种是方法调用模式,如果一个函数作为一个对象的方法来调用时,this 指向这个对象。

  • 第三种是构造器调用模式,如果一个函数用 new 调用时,函数执行前会新创建一个对象,this 指向这个新创建的对象。

  • 第四种是 apply 、 call 和 bind 调用模式,这三个方法都可以显示的指定调用函数的 this 指向。其中 apply 方法接收两个参数:一个是 this 绑定的对象,一个是参数数组。call 方法接收的参数,第一个是 this 绑定的对象,后面的其余参数是传入函数执行的参数。也就是说,在使用 call() 方法时,传递给函数的参数必须逐个列举出来。bind 方法通过传入一个对象,返回一个 this 绑定了传入对象的新函数。这个函数的 this 指向除了使用 new 时会被改变,其他情况下都不会改变。

这四种方式,使用构造器调用模式的优先级最高,然后是 apply 、 call 和 bind 调用模式,然后是方法调用模式,然后 是函数调用模式。

http://cavszhouyou.top/JavaScript深入理解之this详解.html 参考: JavaScript 深入理解之 this 详解 (opens new window)

# eval 是做什么的?

它的功能是把对应的字符串解析成 JS 代码并运行。

应该避免使用 eval,不安全,非常耗性能(2 次,一次解析成 js 语句,一次执行)。

# 什么是 DOM 和 BOM?

DOM 指的是文档对象模型,它指的是把文档当做一个对象来对待,这个对象主要定义了处理网页内容的方法和接口。

BOM 指的是浏览器对象模型,它指的是把浏览器当做一个对象来对待,这个对象主要定义了与浏览器进行交互的法和接口。BOM 的核心是 window,而 window 对象具有双重角色,它既是通过 js 访问浏览器窗口的一个接口,又是一个 Global(全局) 对象。这意味着在网页中定义的任何对象,变量和函数,都作为全局对象的一个属性或者方法存在。window 对象含有 locati on 对象、navigator 对象、screen 对象等子对象,并且 DOM 的最根本的对象 document 对象也是 BOM 的 window 对 象的子对象。

# 截止到 40 题

修改方式:不再整章抄录,只摘抄优秀的回答

上次编辑于: 2025年7月10日 04:01
贡献者: HugStars