笔记:关于JS面试所问问题(beta)

123 阅读4分钟

1.let const var相关

var————ES5变量声明方法
1.在变量未赋值时,变量未undefined(未使用声明变量时也为undefined)
2.作用域————var的作用域为方法作用域;只要在方法内定义了,整个方法内的定义变量后的代码都可以使用

let————ES6变量声明方式
1.在变量生命前直接使用会报错
2.作用域————let为块级作用域,通常let比var范围要小
3.let禁止重复声明变量,否则会报错;var可以重复声明

const————ES6变量声明方式
1.const为常量声明方式;声明变量时必须初始化,在后面出现的代码中不能再修改该常量的值
2.const实际上保证的,并不是变量的值不得改到那个,而是变量指向的那个内存地址不得改动

2.js数据类型,区别

2.1 数据类型

(栈)基本数据类型(原始数据类型): Number,String,Boolean,null,undefined,symbol,bigint(后面两个为ES6新增)
(堆)引用数据类型: object,function(proto Function.prototype),array object:普通对象,数组对象,正则对象,日期对象,Math数学函数对象

2.2 区别

  • 两种数据存储方式:
    基本数据类型是直接存储在栈中的简单数据段,占据空间小、大小固定,属于被频繁使用的数据。栈是存储基本类型值和执行代码的空间
    引用数据类型是存储在堆内存中,占据空间大、大小不固定。引用数据类型在栈中存储了指针,该指针指向堆中该实体的起始地址,当解释器寻找引用值时,会检索其在栈中的地址,取得地址后从队中获得实体。
  • 1.堆比栈空间大,栈比堆运行速度快。
  • 2.堆内存是无序存储,可以根据引用直接获取。
  • 3.基础数据类型比较稳定,而且相对来说占用的内存小。
  • 4.引用数据类型大小是动态的,而且是无限的。

2.3检测数据类型的方法

typeof(检测基本数据类型)可以返回以下类型:undefined、boolean、number、string、object(array和null都是object类型)、function、symbol等

instanceof(用于检测引用类型):A instanceof B 判断A是否为B的实例,如果是返回true,反之返回false。instanceof检测的是原型,内部机制其实就是判断对象A的原型链中是否含有B的原型,

instanceof只能用来判断两个对象是否属于实例关系,而不能判断一个对象实例具体属于哪种类型

constructor:当一个函数F被定义时,Js引擎会为F添加prototype原型,然后在prototype上添加一个constructor属性,并让其指向F的引用。如下图所示:
当执行 var f = new F()时,F被当成了构造函数,f是F的实例对象,此时F原型上的constructor传递到f上,因此f.constructor == F
可以看出,JS在函数F的原型上定义了constructor,当F被当作构造函数用来创建对象时,创建的新对象就被标记为了“F”类型,使得新对象又名有姓,可以追溯。
同理,JS中的数据类型也遵守这个规则:

细节问题:

  1. null和undefined是无效的对象,因此是不会有constructor存在的,这两种类型的数据可以通过toString方法来判断。
  2. JS对象的constructor是不稳定的,这个主要体现在自定义对象上,当开发者重写prototype后,原有的constructor会丢失,constructor会默认为Object

toString(判断类型最准确的方法):toString是Object原型对象上的一个方法,该方法默认返回其调用者的具体类型,更严格的讲,是toString运行时this指向的对象类型,返回的类型默认格式为[object ,xxx],xxx是具体的数据类型,其中包裹String、Number、Boolean、Undefined、Null、Function、Date、Array、RegExp、Error、HTMLDocument...基本上所有对象的类型都可以通过这个方法获取到。

需要注意的是,必须通过Object.prototype.toString.call来获取,而不能直接new Date().toString(),从原型链的角度讲,所有对象的原型链最终都指向Object,按照JS变量查找规则,其他对象应该也可以直接访问到Object的toString方法,而事实上,大部分的对象都实现了自己的toString方法,这样就可能会导致Object的toString被终止查找,因此要用call来强制执行Object的toString方法