阅读 4

面试题训练

1.预编译执行过程

  • 创建AO(activeation object)对象,执行期上下文。

  • 寻找函数的形参和变量声明,将变量和形参名作为AO对象的属性名,值设定为undefined.

  • 将形参和实参相统一,即更改形参后的undefined为具体的形参值。

  • 寻找函数中的函数声明,将函数名作为AO属性名,值为函数体。

2.深浅拷贝

  • 浅拷贝:仅仅是复制了引用,彼此之间的操作会互相影响

  • 深拷贝:在堆中重新分配内存,不同的地址,相同的值,互不影响

  • 深浅拷贝的主要区别就是:复制的是引用还是复制的是实例

    实现浅拷贝的方法

    let arr=[1,2,3]
    1:let arr2=[...arrr]
    2:let arr2=[].concat(arr)
    复制代码

    实现深拷贝的方法

    let arr=[1,2,[3,4,[5,6]]]
    1:let arr2=JSON.parse( JSON.stringify(arr))
    
    复制代码

3.原型和原型链

原型定义:每个函数都有一个prototype属性,这个属性指向一个对象,这个对象称之为原型;

每一个JavaScript对象(null除外)在创建的时候就会与之关联另一个对象,这个对象就是我们所说的原型,每一个对象都会从原型"继承"属性;

原型链定义:

  • 1:Object.prototype为止,所有Object的原型,是一个对象的终极原型;
  • 2:访问实例的一个属性,会先从实例内部查找,若没有,就到它的原型去查找,还没有,就继续向父一级原型查找,一直查找到Object.prototype位置,若有,就返回,没有在返回undefined

4:this指向场景

  • 1.普通函数:this指向window,在严格模式下this是undefined
  • 2:构造函数:this指向创建的实例对象
  • 3:作为对象的方法:this指向调用者,谁调用,指向谁;
  • 4:显示绑定this:通过call,apply,bind可以改变this指向

5.call,apply,bind的区别

相同:

三者的第一个参数都是this指向()

不同:call和apply传参方法不同,前者并排一个接着一个,而后者接受的是一个数组

bind会返回一个新函数,不会立即执行

6.作用域

定义:简单来说,作用域就是能够访问的变量区域范围

作用域分为:全局作用域,局部作用域(函数作用域),还有ES6新添的作用域

在函数内定义的变量,就是局部作用域,否者就是全局作用域,没有使用var关键字也是全局作用域

7.var,let和const的区别

  • var定义的变量,没有块的概念,可以跨块访问, 不能跨函数访问。

  • let定义的变量,不可以重复声明,只能在块作用域里访问,不能跨块访问,也不能跨函数访问。

  • const用来定义常量,不可以重复声明,使用时必须初始化(即必须赋值),只能在块作用域里访问,而且不能修改

  • const定义的变量如果是基本数据类型,不可以改变,如果变量是对象(引用数据类型),不可以重新赋值,但是可以修改这个对象内部的值

  1. new 关键字的作用

    创建一个空对象

    将构造函数的this指向创建的新对象

    返回这个新对象

9.闭包

定义:就是能够访问其他函数内部的变量的函数,也就是说函数A返回函数B,函数B里保存函数A的变量,就会形成闭包

闭包的特性

  • 函数嵌套函数

  • 函数内的变量不会被垃圾回收机制清理

闭包的作用

  • 实现私有数据
  • 模拟块级作用域
  • 实现js的模块划分
  • 避免全局变量污染

注意点:过多的使用闭包,会造成内存泄漏,所以避免滥用闭包

内存泄漏:简单来说,就是会占满内存空间

10.async和defer的区别

deferasync的区别是:defer要等到整个页面在内存中正常渲染结束(DOM 结构完全生成,以及其他脚本执行完成),才会执行;async一旦下载完,渲染引擎就会中断渲染,执行这个脚本以后,再继续渲染。一句话,defer是“渲染完再执行”,async是“下载完就执行”。另外,如果有多个defer脚本,会按照它们在页面出现的顺序加载,而多个async脚本是不能保证加载顺序的。

关注下面的标签,发现更多相似文章
评论