JS相关 | 面试高频问题(一) | async和defer/JS的数据类型判断方法/隐式转换和显式转换/var、let、const区别

1. async和defer的区别(★★★)

答:defer和async都不会阻塞文档的解析,但是不同的是:

  1. async是在下载脚本结束后立即解析。defer不是。
  2. defer按顺序下载和执行,async没有顺序。
  3. defer会在load事件和DOMContentLoad事件之前执行,async在load事件之前执行,对DOMContentLoad事件没有顺序。

详细解释:
一般的渲染的过程是自上而下,同步进行的,也就是说遇到外部的脚本,就得暂停文档的解析,下载并且解释执行,这种方式是阻塞的,会造成网页空白的现象。
关于defer
用于开启新的线程下载脚本文件,并使脚本在文档解析完成后执行。

  1. defer只适用于外联脚本,如果script标签没有指定src属性,只是内联脚本,不要使用defer
  2. 如果有多个声明了defer的脚本,则会按顺序下载和执行
  3. defer脚本会在DOMContentLoaded(document.)和load事件(window.)之前执行

关于async
HTML5新增属性,用于异步下载脚本文件,下载完毕立即解释执行代码。

  1. 适用于外联脚本,这一点和defer一致 。
  2. 如果有多个声明了async的脚本,其下载和执行也是异步的,不能确保彼此的先后顺序。
  3. async会在load事件之前执行,但并不能确保与DOMContentLoaded的执行先后顺序。
  4. async和defer一样,不会阻塞当前文档的解析,它会异步地下载脚本,但和defer不同的是,async会在脚本下载完成后立即执行,如果项目中脚本之间存在依赖关系,不推荐使用async。

在这里插入图片描述
参考

2. JS的数据类型以及判断方法(★★★★★)

JavaScript 中常见的几种数据类型:
基本类型:string, number, boolean
特殊类型:undefined, null
引用类型:Object, Function, Array, RegExp, Date,…

判断方法:(四种)

  1. typeOf
    返回一个表示数据类型的字符串,返回结果包括:number、boolean、string、object、undefined、function等6种数据类型。
  2. instanceof
    用来判断 A 是否为 B 的实例对,表达式为:A instanceof B,如果A是B的实例,则返回true,否则返回false。 instanceof检测的是原型,只能用来判断两个对象是否属于原型链的关系, 而不能获取对象的具体类型。
  3. constructor
    当一个函数F被定义时,JS引擎会为F添加prototype原型,然后再在prototype上添加一个constructor属性,并让其指向F的引用。当F被当作构造函数用来创建对象时,创建的新对象就被标记为了“F” 类型。
    注意:null和undefined是无效的对象,不会有constructor存在的,这两种类型的数据需要通过typeof来判断。
    JS对象的constructor是不稳定的,体现在自定义对象上,当开发者重写prototype后,原有的constructor会丢失,constructor会默认为Object。
  4. Object.prototype.toString
    toString是Object原型对象上的一个方法,该方法默认返回其调用者的具体类型,更严格的讲,是toString运行时this指向的对象类型,
    返回的类型格式为[object,xxx],xxx是具体的数据类型,包括:String, Number, Boolean, Undefined, Null, Function, Date, Array, RegExp, Error, HTMLDocument,…
    基本上所有对象的类型都可以通过这个方法获取到。
    eg: Object.prototype.toString.call( '' ) ; // [object String]

参考自博客

3. 隐式转换和显式转换(★★★)

某些运算符会做隐式的类型转换。eg: x+" " and !! ‘x’ and +x

x+"" // 等价于 String(x)  如88 + '6' => ’886’
+x // 等价于 Number(x).也可以写成x-0  如+'886' => number类型的886
!!x // 等价于Boolean(x) 如 !!'886' => true

显式类型转换最简单的方法就是使用
Boolean()、Number()、String() 或 Object() 函 数。

Number( "3)  // 3
String(false)  // "false" 或使用false.toString()
Object(3) // Number(3)
Boolean([])  // true
Boolean('')  //  false

解释:
Boolean()用的是ToBoolean方法;参数为String中,string长度为0,
也就是空字符串""时,Boolean显式转换为false,非空字符串为true;
参数只要是Object类型,都被Boolean显示转换成true[] 数组属于Object类型的一种。

4. var、let、const作用区别(★★★★★)

在这里插入图片描述

var

  • var 声明一个变量,那么这个变量就属于当前的函数作用域,如果声明是发生在任何函数外的顶层声明,那么这个变量就属于全局作用域。
  • 省略 var,该变量就会变成全局变量,如全局作用域中存在该变量,就会更新其值。
  • 只有变量声明才会提升,对变量赋值并不会提升。

let

  • let 声明的变量具有块作用域的特征。
  • 在同一个块级作用域,不能重复声明变量。
  • let 声明的变量不存在变量提升,就是 let 声明存在暂时性死区(TDZ)。
  • 块级作用域,由花括号括起来的所有的内容。let和const是块作用域,意味着无论你在块中无论定义了什么变量,什么时候定义的,它都不会跑到块作用域外面去。

以下是一个经典的关于 var 和 let 的一个例子:

for (var i = 0; i < 10; i++) {
    setTimeout(function(){
        console.log(i);
    },100)
};
该代码运行后,会在控制台打印出1010.若修改为:
变量i不会被重新定义。它的值只会在每次的迭代中不断地被改变。
他实际上只有一个值 - 就是在最后一次循环赋给的那个值。

for (let i = 0; i < 10; i++) {
    setTimeout(function(){
        console.log(i);
    },100)
}; 
则该代码运行后,就会在控制台打印出0-9.
现在的每一次循环都有它自己的变量定义,所以变量不会被重写。

const

  • 除了具有 let 的上述特点外,其还具备一个特点,即 const 定义的变量,一旦定义后,就不能修改,即 const 声明的为常量。
    但是,并不是说 const 声明的变量其内部内容不可变,如:
const obj = {a:1,b:2};
console.log(obj.a);//1
obj.a = 3;
console.log(obj.a);//3
所以准确的说,是 const 声明创建一个值的只读引用。
但这并不意味着它所持有的值是不可变的,只是变量标识符不能重新分配。

参考

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值