Javascript前端面试(七)

JavaScript 部分

1. JavaScript 有哪些数据类型,它们的区别?

JavaScript 共有八种数据类型,分别是 Undefined、Null、Boolean、

Number、String、Object、Symbol、BigInt。

其中 Symbol 和 BigInt 是 ES6 中新增的数据类型:

●Symbol 代表创建后独一无二且不可变的数据类型,它主要是为了

解决可能出现的全局变量冲突的问题。

●BigInt 是一种数字类型的数据,它可以表示任意精度格式的整数, 使用 BigInt 可以安全地存储和操作大整数,即使这个数已经超出了

Number 能够表示的安全整数范围。

这些数据可以分为原始数据类型和引用数据类型:

●栈:原始数据类型(Undefined、Null、Boolean、Number、String)

●堆:引用数据类型(对象、数组和函数) 两种类型的区别在于存储位置的不同:

●原始数据类型直接存储在栈(stack)中的简单数据段, 占据空间 小、大小固定,属于被频繁使用数据,所以放入栈中存储;

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

●在数据结构中,栈中数据的存取方式为先进后出。

●堆是一个优先队列,是按优先级来进行排序的,优先级可以按照大 小来规定。

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

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

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

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

(1)typeof

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

(2)instanceof

instanceof 可以正确判断对象的类型,其内部运行机制是判断在其

原型链中能否找到该类型的原型。

可以看到,instanceof 只能正确判断引用数据类型,而不能判断基 本数据类型。instanceof 运算符可以用来测试一个对象在其原型链

中是否存在一个构造函数的 prototype 属性。

(3) constructor

constructor 有两个作用,一是判断数据的类型,二是对象实例通过 constr cutor 对象访问它的构造函数。需要注意,如果创建一个对象

来改变它的原型,constructor 就不能用来判断数据类型了:

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

Object.prototype.toString.call() 使用 Object 对象的原型方法

toString 来判断数据类型:

同样是检测对象 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 方法。

3. null  undefined 区别

首先 Undefined 和 Null 都是基本数据类型,这两个基本数据类型

分别都只有一个值,就是 undefined 和 null。undefined 代表的含义是未定义,null 代表的含义是空对象。一般 变量声明了但还没有定义的时候会返回 undefinednull 主要用于

赋值给一些可能会返回对象的变量,作为初始化。undefined 在 JavaScript 中不是一个保留字,这意味着可以使用 undefined 来作为一个变量名,但是这样的做法是非常危险的,它会 影响对 undefined 值的判断。我们可以通过一些方法获得安全的undefined 值,比如说 void 0。当对这两种类型使用 typeof 进行判断时 Null 类型化会返回 “object ”,这是一个历史遗留的问题。当使用双等号对两种类型的值进行比较时会返回 true,使用三个等号时会返回 false。

4. intanceof 操作符的实现原理及实现

instanceof 运算符用于判断构造函数的 prototype 属性是否出现在对象的原型链中的任何位置。

在JavaScript中,instanceof 运算符用于测试一个对象是否在其原型链原型构造函数的 prototype 属性所指向的原型对象上。简而言之,它用来判断一个实例是否属于某个构造函数或类的实例。然而,instanceof 的具体实现是由JavaScript引擎(如V8、SpiderMonkey等)提供的,并且不是直接在ECMAScript规范中定义的算法。不过,我们可以尝试理解其背后的逻辑或自己实现一个类似instanceof的功能。

背后的逻辑

instanceof 操作符的基本逻辑是:

  1. 获取右边操作数的 prototype 属性。
  2. 检查左边操作数的原型链(即 __proto__ 链,现代JavaScript中通常通过 Object.getPrototypeOf() 访问),看是否存在一个原型对象等于右边操作数的 prototype
  3. 如果存在,返回 true;否则,返回 false

注意:__proto__ 是一个非标准但广泛支持的属性,用于访问对象的原型。但建议使用 Object.getPrototypeOf() 来代替,因为它是一个标准且更安全的方法。

实现类似 instanceof 的函数

下面是一个简单的JavaScript函数,实现了类似 instanceof 的功能

function isInstanceOf(obj, constructor) {  
  // 1. 获取构造函数的prototype属性  
  let proto = constructor.prototype;  
  // 2. 遍历obj的原型链  
  while (obj !== null) {  
    // 3. 检查当前原型是否等于构造函数的prototype  
    if (proto === Object.getPrototypeOf(obj)) {  
      return true;  
    }  
    // 4. 否则,继续向上遍历原型链  
    obj = Object.getPrototypeOf(obj);  
  }  
  // 5. 如果遍历完整个原型链都没有找到,返回false  
  return false;  
}  
  
// 使用示例  
function MyClass() {}  
const instance = new MyClass();  
console.log(isInstanceOf(instance, MyClass)); // true  
console.log(isInstanceOf(instance, Object)); // true,因为MyClass的原型链最终指向Object.prototype  
console.log(isInstanceOf(instance, Array)); // false

5. 如何获取安全的 undefined 值?

因为 undefined 是一个标识符,所以可以被当作变量来使用和赋值, 但是这样会影响 undefined 的正常判断。表达式 void     没有返 回值,因此返回结果是 undefinedvoid 并不改变表达式的结果,只是让表达式不返回值。因此可以用 void 0 来获得 undefined。

6. Object.is() 与比较操作符 “=== ”、“==  的区别?

使用双等号(==)进行相等判断时,如果两边的类型不一致,则会进行强制类型转化后再进行比较。

使用三等号(===)进行相等判断时,如果两边的类型不一致时,不会做强制类型准换,直接返回 false。

使用 Object.is 来进行相等判断时,一般情况下和三等号的判断相 同,它处理了一些特殊的情况,比如 -0 和 +0 不再相等,两个 NaN

是相等的。

7. 什么是 JavaScript 中的包装类型?

在JavaScript中,包装类型(Wrapper Types)是一种特殊的对象类型,用于将基本数据类型(如字符串String、数字Number和布尔值Boolean)转换为对象。这些包装类型允许在基本数据类型上执行对象操作,因为它们提供了一组方法和属性,以便更轻松地操作基本数据类型的值。以下是关于JavaScript中包装类型的详细解释:

一、包装类型的定义

在JavaScript中,基本类型(如字符串、数字、布尔值)本身并不具有方法和属性。然而,JavaScript提供了三种包装类型:String、Number和Boolean,这些包装类型允许在基本数据类型上调用对象的方法和访问属性。当在基本类型上调用一个方法时,JavaScript会在后台隐式地将基本类型转换为对应的包装类型来执行操作,这个过程被称为“自动包装”(或称为“装箱”Boxing)。操作完成后,JavaScript会自动将包装类型转换回基本类型,这个过程被称为“自动拆箱”(或称为“拆包”Unboxing)。

二、三种主要的包装类型

  1. String包装类型

    • 用于字符串的包装类型是String。
    • 可以在字符串上调用各种方法,如lengthcharAt()substring()等。
    • 示例:let str = "Hello"; console.log(str.length); // 输出 5
  2. Number包装类型
    • 用于数字的包装类型是Number。
    • 可以在数字上调用各种方法,如toFixed()toPrecision()等。
    • 示例:let num = 123.456; console.log(num.toFixed(2)); // 输出 "123.46"
  3. Boolean包装类型
    • 用于布尔值的包装类型是Boolean。
    • 可以在布尔值上调用方法,如toString()等。
    • 示例:let bool = true; console.log(bool.toString()); // 输出 "true"

三、自动装箱与自动拆箱

  • 自动装箱:当你使用基本数据类型的值(如字符串、数字、布尔值)调用对象方法或访问属性时,JavaScript会自动创建对应的包装对象,以便执行操作。
  • 自动拆箱:当你完成对包装对象的操作后,JavaScript会自动将其拆箱,将包装对象转换回基本数据类型的值。

四、使用包装类型的注意事项

  1. 性能开销:自动装箱和自动拆箱会引入额外的性能开销,特别是在大规模循环或高频率的操作中。
  2. 类型不匹配:由于自动装箱和拆箱,可能会导致类型不匹配的问题。
  3. 对象引用:当你比较两个对象包装器时,它们的引用而非值会被比较,这可能导致不期望的结果。
  4. 陷阱在条件语句中:在条件语句中,自动装箱可能导致出乎意料的结果。例如,一个Boolean对象在布尔上下文中总是被视为true,无论它包装的值是true还是false。

五、总结

包装类型是JavaScript中一个重要的概念,它允许在基本类型上调用对象方法和访问属性,从而增强了JavaScript的灵活性和功能性。然而,在使用时需要注意其性能和类型匹配问题,并避免在性能关键的部分频繁进行自动装箱和拆箱操作。在可能的情况下,直接使用基本类型而不是包装类型通常是一个更好的选择。

8.为什么会有BigInt的提案?
JavaScript 中 Number.MAX_SAFE_INTEGER表示最大安全数字,计算结果是9007199254740991,即在这个数范围内不会出现精度丢失(小数除外)。但是一旦超过这个范围,js就会出现计算不准确的情况,这在大数计算的时候不得不依靠一些第三方库进行解决,因此官方提出了BigInt 来解决此问题。

9.如何判断一个对象是空对象

使用JSON自带的.stringtify()方法判断

if(Json.stringtify(obj)=='{}'){

      console.log('空对象')

}

使用ES6新增的方法Object.keys()来判读:

if(Object.keys(obj).length<0){

     console.log('空对象')

}

10.const对象的属性可以修改吗
    const保证的并不是变量的值不能改动,而是变量指向的那个内存地址不能改动。对于基本类型的数据(数值、字符串、布尔值),其值就保存在变量指向的那个内存地址,因此等同于常量。
但对于引用类型的数据(主要是对象和数组)来说,变量指向数据的内存地址,保存的只是一个指针,const只能保证这个指针是固定不变的,至于它指向的数据结构是不是可变的,就完全不能控制了。


 

 

  • 22
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Ubuntu是一种广受欢迎的开源操作系统,它基于Linux内核,并提供了友好的图形界面和丰富的应用程序。虽然Ubuntu在许多方面表现出色,但有时候也会遇到“暂时资源不够”的问题。 一般来说,Ubuntu中的“暂时资源不够”可能指的是系统的硬件资源不足。硬件资源包括内存、存储空间和处理器等。如果系统的内存不足,那么运行大型程序或多个应用程序可能会导致系统响应变慢或崩溃。如果存储空间不足,那么安装新的软件或保存文件可能会受到限制。而处理器是系统的计算核心,如果处理器性能不足,那么系统的速度和响应性能可能会受到影响。 为了解决这个问题,我们可以采取一些措施来优化系统资源。首先,我们可以关闭不必要的后台进程和服务,以释放一部分内存和处理器资源。其次,我们可以清理临时文件和不常用的应用,以释放存储空间。如果系统的硬件资源确实无法满足我们的需求,那么可以考虑升级硬件,例如增加内存或更换更快的处理器。 此外,我们还可以使用一些优化工具和技巧来提高系统性能。例如,可以调整系统的电源管理策略,以充分利用硬件资源。还可以使用优化的文件系统和缓存机制,以加快文件读写速度。此外,我们还可以根据具体的使用情况,对系统进行进一步的优化和调整。 综上所述,Ubuntu遇到“暂时资源不够”的问题是可能的,但我们可以采取一些措施来优化系统资源,提高系统性能。通过合理的硬件配置和优化技巧,我们可以更好地使用Ubuntu操作系统。 ### 回答2: 当在使用Ubuntu时遇到"暂时资源不够"的问题时,可能是因为系统当前的资源(如内存、磁盘空间)不足以满足正在执行的操作需求。 有几种处理这个问题的方法: 1. 释放内存:可以通过关闭一些不必要的程序或服务来释放内存。也可以使用系统自带的进程管理器来查看哪些应用程序占用了较多的资源,然后结束它们。 2. 清理磁盘空间:可以通过删除一些不再需要的文件或移动它们到其他存储设备来释放磁盘空间。也可以使用系统工具如BleachBit来清理临时文件、浏览器缓存等。 3. 增加物理内存:如果频繁出现资源不足问题,考虑增加计算机的物理内存(RAM)。更多的内存可以提高系统的整体性能和运行效率。 4. 调整系统设置:有时候,通过更改一些系统设置可以改善Ubuntu的性能。例如,可以调整虚拟内存设置,增加Swap分区的大小,以提供更多的虚拟内存。 5. 优化应用程序:一些特定的应用程序可能会占用大量资源,导致系统资源不足。尝试升级或替换这些应用程序,或者找到更轻量级的替代方案。 总之,当Ubuntu出现"暂时资源不够"的问题时,我们可以通过释放内存、清理磁盘空间、增加物理内存、调整系统设置、优化应用程序等方法来解决问题,提高系统的性能和稳定性。 ### 回答3: Ubuntu是一个自由且开源的操作系统,它是基于Linux的,并且被广泛应用于个人电脑、服务器以及其他嵌入式设备中。尽管Ubuntu在很多方面表现出色,但它也有一些可能导致暂时资源不够的限制。 首先,由于Ubuntu是开源的,用户可以根据自己的需求自由安装软件。然而,随着软件数量的增加,可能会占用大量的存储空间。因此,在安装大量软件时可能会出现暂时资源不够的情况,特别是如果硬盘容量较小。 其次,Ubuntu的硬件要求相对较低,但在某些情况下,硬件的性能限制可能导致资源不够。例如,对于一些旧款的电脑,它们的处理器和内存可能无法满足一些较为复杂的应用程序或任务的要求,从而导致暂时资源不足的情况。 此外,一些特定的应用程序或任务可能对系统资源的需求较高,而Ubuntu并没有针对这些应用程序或任务进行优化。因此,在执行这些特定任务时,可能会出现暂时资源不够的问题。 虽然Ubuntu可能会面临一些资源不足的限制,但它依然是一个功能强大且稳定的操作系统。对于资源有限或要求不高的用户来说,Ubuntu仍然是一个不错的选择。同时,通过合理使用资源,如定期清理不必要的文件、关闭不需要的后台程序等,也可以减少暂时资源不够的现象出现。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值