# JS基础
# 说说JavaScript中的数据类型有哪些,他们在存储上的差别是什么?
分为基础类型和引用类型:
- 基础类型:undefined、null、布尔值(Boolean)、字符串(String)、数值(Number)、symbol(es6新增)
- 引用类型:对象(Object)、数组、Function
基础类型存储在栈内存中,引用类型存储在堆内存中
# 深拷贝浅拷贝的区别?如何实现一个深拷贝?
# 深浅拷贝的区别
浅拷贝是拷贝一层,属性为对象时,浅拷贝是复制,两个对象指向同一个地址 深拷贝是递归拷贝深层次,属性为对象时,深拷贝是新开栈,两个对象指向不同的地址
# 浅拷贝的现象有
- Object.assign
- Array.prototype.slice(), Array.prototype.concat()
- 使用拓展运算符实现的复制
# 深拷贝
深拷贝开辟一个新的栈,两个对象属完成相同,但是对应两个不同的地址,修改一个对象的属性,不会改变另一个对象的属性
- 实现
- _.cloneDeep()
- jQuery.extend()
- JSON.stringify() 但是这种方式存在弊端,会忽略undefined、symbol和函数
- 手写循环递归
# == 和 ===区别,分别在什么情况使用
- 等于操作符(==)在比较中会先进行类型转换,再确定操作数是否相等
- 全等操作符由 3 个等于号( === )表示,只有两个操作数在不转换的前提下相等才返回 true。即类型相同,值也需相同
- null 和 undefined 比较,相等操作符(==)为true,全等为false
除了在比较对象属性为null或者undefined的情况下,我们可以使用相等操作符(==),其他情况建议一律使用全等操作符(===)
# 谈谈this对象的理解
this 关键字是函数运行时自动生成的一个内部对象,只能在函数内部使用,总指向调用它的对象
# 绑定规则
- 默认绑定
- 严格模式下,不能将全局对象用于默认绑定,this会绑定到undefined,只有函数运行在非严格模式下,默认绑定才能绑定到全局对象
- 隐式绑定
- 函数还可以作为某个对象的方法调用,这时this就指这个上级对象
- 函数中包含多个对象,尽管这个函数是被最外层的对象所调用,this指向的也只是它上一级的对象
- new绑定
- new关键字生成一个实例对象,此时this指向这个实例对象
- 执行new操作符,其实JS内部完成了以下事情:
- 创建一个空的简单JavaScript对象(即{});
- 将构造函数的prototype绑定为新对象的原型对象 ;
- 将步骤1新创建的对象作为this的上下文并执行函数 ;
- 如果该函数没有返回对象,则返回this。
- 显示绑定
- apply()、call()、bind()是函数的一个方法,作用是改变函数的调用对象。
- 它的第一个参数就表示改变后的调用这个函数的对象。因此,这时this指的就是这第一个参数
# 箭头函数
- 在代码书写时就能确定 this 的指向(编译时绑定)
- 箭头函数在自己的作用域内不绑定 this,即没有自己的 this,如果要使用 this ,就会指向定义时所在的作用域的 this 值
# 优先级
- new绑定优先级 > 显示绑定优先级 > 隐式绑定优先级 > 默认绑定优先级
# JavaScript中执行上下文和执行栈是什么?
执行上下文是一种对Javascript代码执行环境的抽象概念,也就是说只要有Javascript代码运行,那么它就一定是运行在执行上下文中
# 类型分为三种
- 全局执行上下文:只有一个,浏览器中的全局对象就是 window对象,this 指向这个全局对象
- 函数执行上下文:存在无数个,只有在函数被调用的时候才会被创建,每次调用函数都会创建一个新的执行上下文
- 每次调用函数创建一个新的上下文,会创建一个私有作用域,函数内部声明的任何变量都不能在当前函数作用域外部直接访问
- Eval 函数执行上下文: 指的是运行在 eval 函数中的代码,很少用而且不建议使用
# 执行栈
执行栈,也叫调用栈,具有 LIFO(后进先出)结构,用于存储在代码执行期间创建的所有执行上下文
# 流程
- 当Javascript引擎开始执行你第一行脚本代码的时候,它就会创建一个全局执行上下文然后将它压到执行栈中
- 每当引擎碰到一个函数的时候,它就会创建一个函数执行上下文,然后将这个执行上下文压到执行栈中
- 引擎会执行位于执行栈栈顶的执行上下文(一般是函数执行上下文),当该函数执行结束后,对应的执行上下文就会被弹出,然后控制流程到达执行栈的下一个执行上下文
# typeof 与 instanceof 区别
- typeof会返回一个变量的基本类型,instanceof返回的是一个布尔值
- instanceof 可以准确地判断复杂引用数据类型,但是不能正确判断基础数据类型
- 而typeof 也存在弊端,它虽然可以判断基础数据类型(null 除外),但是引用数据类型中,除了function 类型以外,其他的也无法判断
可以看到,上述两种方法都有弊端,并不能满足所有场景的需求
如果需要通用检测数据类型,可以采用Object.prototype.toString,调用该方法,统一返回格式“[object Xxx]”的字符串
# bind、call、apply 区别?如何实现一个bind?
- 三者都可以改变函数的this对象指向
- 三者第一个参数都是this要指向的对象,如果如果没有这个参数或参数为undefined或null,则默认指向全局window
- 三者都可以传参,但是apply是数组,而call是参数列表,且apply和call是一次性传入参数,而bind可以分为多次传入
- bind是返回绑定this之后的函数,apply、call 则是立即执行
# ajax原理是什么?如何实现?
AJAX全称(Async Javascript and XML)即异步的JavaScript 和XML 是一种创建交互式网页应用的网页开发技术,可以在不重新加载整个网页的情况下,与服务器交换数据,并且更新部分网页
# Ajax的原理
简单来说通过XmlHttpRequest对象来向服务器发异步请求,从服务器获得数据,然后用JavaScript来操作DOM而更新页面
- 实现 Ajax异步交互需要服务器逻辑进行配合,需要完成以下步骤:
- 创建 Ajax的核心对象 XMLHttpRequest对象
- 通过 XMLHttpRequest 对象的 open() 方法与服务端建立连接
- 构建请求所需的数据内容,并通过XMLHttpRequest 对象的 send() 方法发送给服务器端
- 通过 XMLHttpRequest 对象提供的 onreadystatechange 事件监听服务器端你的通信状态
- 接受并处理服务端向客户端响应的数据结果
- 将处理结果更新到 HTML页面中
JS重点考查内容 →