js有哪些内置对象?
JavaScript有许多内置对象,包括但不限于:
- 基本对象: Object、Boolean、Symbol、Number、String
- 符合数据结构:Array、Set、Map、WeakSet、WeakMap
- 日期和时间对象:Date
- 数学计算对象:Math
- 正则表达式对象:RegExp
- 函数对象:Function
- 错误对象:Error、TypeError、RangeError等
- 其他对象:Global、JSON等
什么是闭包?
闭包是指一个函数可以访问另一个函数作用域内的变量。当一个函数嵌套在另一个函数中时,内部函数可以访问外部函数的变量,即使外部函数已经返回了。这种情况下,内部函数形成了一个闭包,它保留了外部函数的作用域链并可以继续访问这些变量。闭包常常用于实现函数的封装和私有化,以及在回调和事件处理等场景下的数据共享与传递。
如何理解作用域、作用域链和执行上下文?
在JavaScript中,作用域、作用域链和执行上下文是密切相关的概念,它们与变量和函数的查找、访问以及生命周期有关。
-
作用域(Scope):
作用域是一个变量或函数的可访问范围。JavaScript中有三种作用域:全局作用域、局部(函数)作用域和块级作用域。全局作用域中声明的变量和函数可以在整个代码中访问,局部作用域中声明的变量和函数只能在特定的函数内部访问,块级作用域在一对花括号内定义,对
let
和const
关键字声明的变量有效。变量的生命周期受其作用域的限制。全局作用域中的变量在整个程序执行过程中持续存在,局部作用域中的变量在函数执行结束时销毁,块级作用域在代码块执行结束时,块级作用域中的变量将被销毁。
-
作用域链(Scope Chain):
当代码执行过程中访问一个变量或函数时,JavaScript引擎会沿着作用域链查找该标识符。作用域链是由当前执行上下文的作用域和其所有父级作用域组成的链表。
查找过程从当前作用域开始,然后逐级向上查找,直到找到目标标识符或到达全局作用域。如果在全局作用域中仍未找到目标标识符,则返回
undefined
。 -
执行上下文(Execution Context):
执行上下文是JavaScript代码执行过程中的环境。每当进入一个新的函数执行或全局代码执行时,都会创建一个新的执行上下文。执行上下文包含了当前执行的代码所需的所有信息,如变量、函数、作用域链等。
JavaScript引擎使用执行上下文栈(Execution Context Stack)来管理执行上下文。栈顶的执行上下文为当前执行的代码环境。当一个函数被调用时,一个新的执行上下文被压入栈顶;当函数执行结束时,执行上下文从栈顶弹出,返回到调用者的上下文环境。
总结起来,作用域是变量和函数的可访问范围;作用域链是由当前执行上下文的作用域和其父级作用域组成的链表,用于在代码执行过程中查找变量和函数;执行上下文是代码执行过程中的环境,包含了当前执行的代码所需的所有信息。这三者共同决定了代码执行过程中变量和函数的查找、访问以及生命周期。
如何创建一个没有原型的对象?
可以使用 Object.create(null) 方法创建一个没有原型的对象。这个方法创建一个全新的对象并将其原型设置为 null,因此它没有继承任何属性或方法。例如:
const obj = Object.create(null); console.log(obj.toString); // undefined
如何理解原型链?
原型链是 JavaScript 中实现继承的一种机制,它通过让一个对象的原型指向另一个对象,从而使得一个对象可以访问另一个对象中定义的属性和方法。当我们试图访问一个对象中不存在的属性或方法时,JavaScript 引擎会沿着原型链一直向上查找,直到找到该属性或方法为止,或者最终抵达 Object.prototype(所有对象的祖先)上停止查找。
let const var比较
- 作用域:
var
:声明的变量具有函数作用域。这意味着在函数内部声明的变量只能在该函数内部访问,而在函数外部声明的变量具有全局作用域。let
和const
:声明的变量具有块级作用域。这意味着变量仅在声明它们的代码块(例如:if
语句、for
循环、while
循环等)内部可访问。
- 变量提升(Hoisting):
var
:声明的变量会被提升到所在作用域的顶部。这意味着在声明之前访问变量不会导致引用错误,但变量的值将是undefined
。let
和const
:声明的变量不会被提升。在声明之前访问变量会导致引用错误。
- 重复声明:
var
:允许在同一作用域内多次声明同名变量,后续声明将被忽略。let
和const
:在同一作用域内不允许重复声明同名变量。尝试这样做会导致语法错误。
- 变量的可变性:
var
和let
:声明的变量可被重新赋值。const
:声明的变量是不可变的,即一旦赋值,无法更改。这对于声明常量或确保某个变量在整个程序执行过程中保持不变的情况非常有用。
JSON.stringify有什么缺点?
JSON.stringify()
是一个将JavaScript对象转换为JSON字符串的方法。尽管它在许多情况下非常有用,但它确实存在一些限制和缺点:
- 循环引用:
JSON.stringify()
无法处理具有循环引用的对象。如果一个对象的属性直接或间接引用了自身,JSON.stringify()
将抛出一个错误,表示存在循环引用。 undefined
、函数和Symbol忽略:JSO