1.JavaScript规定了几种语言类型?
基本数据类型:number、string、boolean、null、undefined、symbol(es6)
对象引用类型:Array、Function、Object、RegExp、Error、Date
2.JavaScript对象的底层数据结构是什么?
JavaScript 对象的底层数据结构是哈希表(Hash Table)。在 JavaScript 中,对象是一种无序键值对的集合,其中键是字符串类型,值可以是任何类型。为了快速地访问和修改对象的属性,JavaScript 引擎使用了哈希表来实现对象。哈希表是一种基于键值对的数据结构,它通过将键映射为一个索引来实现快速的查找和插入操作。在 JavaScript 中,哈希表被称为对象的属性表。
3.Symbol类型在实际开发中的应用、可手动实现一个简单的Symbol?
Symbol 是 JavaScript 中的一种基本数据类型,用于表示独一无二的值。如果想手动实现一个简单的 Symbol,可以按照以下步骤进行:
(1)创建一个闭包,用于保存已经创建的 Symbol 值。
(2)在闭包中定义一个内部计数器,用于生成唯一的标识符。
(3)定义一个函数,用于创建新的 Symbol 值。
(4)在函数中生成一个唯一的标识符,并将其保存到闭包中。
(5)返回这个标识符。
下面是一个简单的实现示例:
const createSymbol = (() => {
const symbols = {};
let count = 0;
return (description) => {
const symbol = `Symbol(${description || ''})_${count++}`;
symbols[symbol] = true;
return symbol;
};
})();
const symbol1 = createSymbol('foo');
const symbol2 = createSymbol('bar');
console.log(symbol1); // "Symbol(foo)_0"
console.log(symbol2); // "Symbol(bar)_1"
console.log(symbol1 === symbol2); // false
这个实现生成的 Symbol 值类似于 JavaScript 中的内置 Symbol 值,每个值都是唯一的并且不可变。但是需要注意的是,这个实现是不完整的,它没有实现 Symbol 的所有特性,比如说无法使用 typeof
操作符判断一个值是否为 Symbol。
4.JavaScript中的变量在内存中的具体存储形式?
在 JavaScript 中,变量的具体存储形式取决于变量的数据类型。基本数据类型的变量(如数字、字符串等)通常直接存储在栈中,而对象类型的变量(如数组、对象等)则存储在堆中,而变量名则存储在栈中,并指向相应的内存地址。函数作为一种特殊对象类型,也被存储在堆中。当变量被声明时,JavaScript 引擎会自动分配内存,并在变量赋值时将值存储在相应的内存位置。当变量不再被使用时,JavaScript 引擎会自动处理内存回收,以便释放不再使用的内存。
5.基本类型对应的内置对象,以及他们之间的装箱拆箱操作?
在 JavaScript 中,基本类型和对应的内置对象之间可以进行装箱和拆箱操作。装箱操作指的是将基本类型的值转换为对应的内置对象,拆箱操作则是将内置对象转换为基本类型的值。例如,可以使用以下方式进行装箱操作:
// 字符串装箱
const str = 'hello';
const strObj = new String(str);
// 数字装箱
const num = 123;
const numObj = new Number(num);
// 布尔值装箱
const bool = true;
const boolObj = new Boolean(bool);
可以使用以下方式进行拆箱操作:
// 字符串拆箱
const strObj = new String('hello');
const str = strObj.valueOf();
// 数字拆箱
const numObj = new Number(123);
const num = numObj.valueOf();
// 布尔值拆箱
const boolObj = new Boolean(true);
const bool = boolObj.valueOf();
需要注意的是,基本类型和对应的内置对象并不完全等价。例如,对于字符串类型,基本类型的值是不可变的,而字符串对象是可变的。因此,在进行比较时应该使用严格相等运算符"===" 而不是相等运算符。
由于 JavaScript 引擎在处理基本类型和对象类型时的内部实现方式不同,装箱和拆箱操作可能会产生一定的性能开销。因此,在开发中应尽量避免不必要的装箱和拆箱操作,尽量使用基本类型进行数值计算和比较操作。
JavaScript 是一种动态类型语言,它的变量可以存储不同类型的值,包括基本类型和对象类型。为了方便开发者在处理基本类型和对象类型时可以统一使用相同的语法和操作符,JavaScript 引入了装箱和拆箱操作。
装箱操作是将基本类型的值转换为对应的对象类型,这样就可以使用对象的方法和属性对其进行操作。例如,使用字符串对象的 length
属性获取字符串的长度。拆箱操作则是将对象类型转换为基本类型的值,这样就可以直接进行数值计算和比较操作。
如图通过装箱操作的对象可以调用对象的方法,字面量创建会报错
6.理解值类型和引用类型?
值类型的特点是它们的值在内存中占据独立的空间,每个变量在内存中都有自己的副本,因此它们之间的比较是按值比较的。
引用类型的特点是它们的值在内存中不是独立存在的,而是存储在内存中的对象中,变量保存的是对象的地址,因此它们之间的比较是按引用比较的。
当我们对值类型进行赋值时,会在内存中创建一个新的值,变量指向这个新的值。而对引用类型进行赋值时,只是将变量指向内存中的对象,而不是创建一个新的对象。
理解值类型和引用类型对于理解 JavaScript 中的变量赋值、函数参数传递、对象属性访问等操作非常重要。
7.null和undefined的区别?
在JavaScript中,null和undefined是两个不同的值,它们有以下区别:
- undefined表示一个变量没有被定义或者没有被赋值,而null表示变量被显式地赋值为null。
- 如果一个函数没有返回值,它将默认返回undefined,而不是null。
- 当使用==,运算符时,null和undefined被认为是相等的,但当使用===运算符时,它们被认为是不相等的。
- 当访问对象的属性时,如果属性不存在,将返回undefined,而不是null。
总之,null表示一个空值,而undefined表示一个未定义的值。
8.至少可以说出三种判断JavaScript数据类型的方式,以及他们的优缺点,如何准确的判断数组类型?
- typeof 运算符:可以用来判断大多数基本数据类型,返回值为字符串。例如:typeof 123 返回 “number”,typeof “hello” 返回 “string”。
原理:typeof 运算符返回一个字符串,表示未经计算的操作数的类型。它对于大多数基本数据类型都可以正确判断,但对于 null 和一些对象类型如 Date、Array 等则有限制。 - instanceof 运算符:可以用来判断对象的具体类型,返回值为布尔值。例如:[] instanceof Array 返回 true,new Date() instanceof Date 返回 true。
原理:instanceof 运算符通过判断一个对象是否是某个构造函数的实例来判断其类型。例如,[] instanceof Array 表示空数组 [] 是否是 Array 构造函数的实例,如果是则返回 true,否则返回 false。 - Object.prototype.toString 方法:可以用来判断大多数数据类型,返回值为字符串。例如:Object.prototype.toString.call([]) 返回 “[object Array]”,Object.prototype.toString.call({}) 返回 “[object Object]”。
原理:Object.prototype.toString 方法返回一个表示对象的字符串,其中 [object Type] 中的 Type 表示对象的具体类型。通过使用 call 方法可以将该方法应用于不同的对象。 - Array.isArray 方法:可以用来判断是否为数组类型,返回值为布尔值。例如:Array.isArray([]) 返回 true,Array.isArray({}) 返回 false。
原理:Array.isArray 方法用于判断一个对象是否为数组类型。如果是数组则返回 true,否则返回 false。
9.可能发生隐式类型转换的场景以及转换原则,应如何避免或巧妙应用?
Number.toString()
String(null) // 'null'
String(undefined) // 'undefined'
Number('123') // 123
Number(null) // 0
Number(false) // 0
Number('') // 0
Number(true) // 1
parseFloat('111.111.111') // 111.111
Number(undefined) // NaN
Number('a') // NaN
parseFloat('a111.111') // NaN
Bollean(0) // false
Bollean('') // false
Bollean(null) // false
Bollean(NaN) // false
Bollean(undefined) // false
// +
'1' + 1 // '11'
'a' + 1 // 'a1'
// -、*、/、%
1 - '2' // -1
1 - 'a' // NaN
1 * '2' // 2
1 * 'a' // NaN
1 / '2' // 2
1 / 'a' // NaN
1 % '2' // 2
1 % 'a' // NaN
// ==
'' == false // 0 == 0 true
0 == false // 0 == 0 true
10.出现小数精度丢失的原因,JavaScript可以存储的最大数字、最大安全数字,JavaScript处理大数字的方法、避免精度丢失的方法?
作者:ConardLi
链接:https://juejin.cn/post/6844903830887366670
来源:稀土掘金