那些JS中常见的面试题及知识点
1.什么是闭包
当一个函数的返回值是另一个函数,返回的那个函数如果调用了父函数的内部变量,且在外部被执行就产生了闭包
特性
1.函数套函数,
2.内部函数访问外部函数变量,参数
3.变量和参数不会被垃圾回收机制回收
优点
1.变量长期住在在内存中
2.不会造成全局污染
3.私有成员的存在
缺点
常驻内存增大内存的使用量,使用不当会造成内存的泄露
2.原型和原型链
原型概念:
原型概念:jsvascript都包含了一个proto内部属性,这个属性对应的是自身。
除了原型proto之外,还有prototype属性,当函数对象作为构造函数创建实例时,prototype属性值将被作为 实例对象的原型proto
原型链的概念:原型链当一个对象调用自身不存在的对象或者方法就会去自己proto关联的前辈prototype对象上去找,如果没有找到,就会去prototype原型proto关联的前辈prototype,依次类推直到undefined,这就是原型链。
例如:B继承A的原型上的方法,C继承B原型上的方法,这时C._proto_指向B的原型,B._proto指向A的原型这就行程了原型链
隐式原型:用来构成原型链,实现基于原型的继承
显示原型:用来实现原型的继承与属性共享
3.组合继承
// 父
function Person(name, age) {
this.name = name
this.age = age
//方法一
// this.say=function(){
// console.log(this.name)
// }
}
//方法二
Person.prototype.say = function () { console.log(this.name) }
// 子
function stu(name, age) {
Person.call(this, name, age)
}
//继承他的方法
stu.prototype.say = Person.prototype.say
var s = new stu(“张三”, 33)
console.log(s)
4.说一下JS原生事件如何绑定
一、是html事件处理程序
html事件现在早已不用了,就是在html各种标签上直接添加事件,类似于css的行内样式,缺点是不好维护
例如:<button οnclick="时间处理函数”>点我
二、是DOM0级事件处理程序
目前在PC端用的还是比较多的绑定事件方式,兼容性也好,主要是先获取dom元素,然后直接给dom元 素添加事件
DOM0事件如何移除呢?很简单:btn.onclick=null;置为空就行
优点:兼容性好
缺点:只支持冒泡,不支持捕获
三、是DOM2级事件处理程序
移动端用的比较多,也有很多优点,提供了专门的绑定和移除方法
优点:支持给个元素绑定多个相同事件,支持冒泡和捕获事件机制
5.说一下JS原生常用dom操作方法?
查找:
getElementByid,
getElementsByTagName
querySelector
querySelectorAll
插入:
appendChild
insertBefore
删除:
removeChild
克隆:
cloneNode
设置和获取属性:
setAttribute(“属性名”,”值”)
getAttibute(“属性名”)
6.ES6新增特性
1.新增了块级作用域(let,const)
2.提供了定义类的语法糖(class)
3.新增了一种基本数据类型(Symbol)
4.新增了变量的解构赋值
5.函数参数允许设置默认值,引入了rest参数,新增了箭头函数
6.数组新增了一些API,如 isArray / from / of 方法;数组实例新增了 entries(),keys() 和 values() 等方法
7.对象和数组新增了扩展运算符
8.ES6 新增了模块化(import/export)
9.ES6 新增了 Set 和 Map 数据结构
10.ES6 原生提供 Proxy 构造函数,用来生成 Proxy 实例
11.ES6 新增了生成器(Generator)和遍历器(Iterator)
7.JS设计模式有哪些(常见的三种)
1.单例模式
2.工厂模式
3.构造函数模式
8.说一下你对JS面向对象的理解
JS面向对象主要基于function来实现的,通过function来模拟类,通过prototype来实现类方法的共享
9.说一下JS数组常用方法
push
pop
unshift
shift
splice
join
concat
forEach
filter
map
sort
some
every
10.说一下JS数组内置遍历方法有哪些和区别
forEach
这个方法是为了取代for循环遍历数组的,返回值为undefined
filter
是一个过滤遍历的方法,如果返回条件为true,则返回满足条件为true的新数组
map
这个map方法主要对数组的复杂逻辑处理时用的多,特别是react中遍历数据,也经常用到,写法和forEach 类似
some
这个some方法用于只要数组中至少存在一个满足条件的结果返回值就为true,否则返回fasel
写法和forEach类似
every
这个every方法用于数组中每一项都得满足条件时,才返回true,否则返回false, 写法和forEach类似
11.说一下JS作用域
在 JavaScript 中, 作用域为可访问变量,对象,函数的集合。
1.JavaScript 局部作用域
变量在函数内声明,变量为局部作用域。
局部变量:只能在函数内部访问
2.JavaScript全局作用域
也就是定义在window下的变量范围,在任何地方都可以访问,
3.JavaScript块级作用域
块级作用域:简单来说用let和const在任意的代码块中定义的变量都认为是块级作用域中的变量
注:
1. 尽量不要使用全局变量,因为容易导致全局的污染,命名冲突,对bug查找不利。
2. 而所谓的作用域链就是由最内部的作用域往最外部,查找变量的过程.形成的链条就是作用域链
12. 从输入URL到页面加载完中间发生了什么
1.DNS解析(解析URL对应的IP
2.TCP 连接(三次握手)
3.发送 HTTP 请求
4.服务器处理请求并返回需要的数据
5.浏览器解析渲染页面
6.连接结束(四次挥手)
三次握手
三次握手是连接协议
四次挥手
关闭连接是四次协议
13.JS事件代理(也称事件委托)是什么,及实现原理
JS事件代理就是通过给父级元素绑定事件,不给子级元素绑定事件。然后当点击子级元素时,通过事件冒泡机制在其绑定的父元素上触发事件处理函数主要目的是为了提升性能
特别是给动态添加的元素绑定事件,这个特别起作用
14.说一下js数据类型有哪些
js数据类型有:
1.基本数据类型:
number
string
Boolean
null
undefined
symbol(ES6新增)
2.复合类型
Object
function
15.说一下 call,apply,bind区别
call,apply,bind主要作用都是改变this指向的,但使用上略有区别
call和apply的主要区别是在传递参数上不同
1.call后面传递的参数是以逗号的形式分开的
2.apply传递的参数是数组形式
bind返回的是一个函数形式如果要执行,则后面要再加一个小括号
16.JavaScript的作用域链理解
其本质是JavaScript在执行过程中会创造可执行上下文,可执行上下文中的词法环境中含有外部词法环境的引用,我们可以通过这个引用获取外部词法环境的变量、声明等,这些引用串联起来一直指向全局的词法环境,因此形成了作用域链。
17.ES6模块与CommonJS模块有什么区别
ES6 Module和CommonJS模块的区别:
CommonJS是对模块的浅拷贝,ES6 Module是对模块的引用,即ES6 Module只存只读,不能改变其值,具体点就是指针指向不能变,类似const
import的接口是read-only(只读状态),不能修改其变量值。 即不能修改其变量的指针指向,但可以改变变量内部指针指向,可以对commonJS对重新赋值(改变指针指向),
ES6 Module和CommonJS模块的共同点:
CommonJS和ES6 Module都不可以对引入的对象进行赋值,即对对象内部属性的值进行改变。
18.null与undefined的区别是什么
null表示为空,代表此处不应该有值的存在,一个对象可以是null,代表是个空对象,而null本身也是对象。
undefined表示『不存在』,JavaScript是一门动态类型语言,成员除了表示存在的空值外,还有可能根本就不 存在(因为存不存在只在运行期才知道),这就是undefined的意义所在
19.箭头函数的this指向
箭头函数并没有属于自己的this,它的所谓的this是捕获其所在上下文的 this 值,作为自己的 this 值,并且由于 没有属于自己的this,而箭头函数是不会被new调用的,这个所谓的this也不会被改变.
20.async/await
是一套关于异步解决的方案
两个作用1.求值关键字2.异步操作变为同步操作
- async会返回一个promise对象,执行时遇到await就会先返回,触发异步操作完成后,再接着执行函数后面的语句
- 优势就在于改善pramise的.then链
- await必须在async的函数内部使用
- awati后面必须要跟一个promise(不是的话用reslove转换他)
- await的返回结果就是后面promise执行的结果
21.async/await相比于Promise的优势
1.代码读起来更加同步,改善Promise.then链
2.Promise传递中间值非常麻烦,async/await几乎是同步的写法,看着简洁明了
3.错误处理友好,async/await可以用成熟的try/catch,Promise的错误捕获非常冗余
4.调试友好,Promise的调试很差。
22.JavaScript的基本类型和复杂类型是储存在哪里的
基本类型储存在栈中
复杂类型会储存在内存堆中
23.栈和堆的区别
栈:
1.存储基本数据类型
2.存储空间小
3.查找迅速性能高
堆:
1.存多个值得复合类型
2.存储空间大
3.查找速度慢性能较低
24.深拷贝和浅拷贝的区别
深拷贝和浅拷贝是针对复杂的数据类型来说的浅拷贝只拷贝一层,深拷贝是层层拷贝
深拷贝:
复制变量值,对于非基本类型的变量,递归到基本类型再复制。与原对象完全隔离互不影响。
最简单的实现是json.parse(json.stringfy(obj))
浅拷贝:
复制属性,只拷贝第一层属性,当前对象的属性值是引用类型时,实质复制的是引用,引用的值也会发生变化
可以使用for in、object.assign、扩展运算符、递归等来实现
25.浏览器是如何渲染页面的
渲染的流程如下:
1.解析HTML文件,创建DOM树。
自上而下,遇到任何样式(link、style)与脚本(script)都会阻塞(外部样式不阻塞后续外部脚本的加载)。
2.解析CSS。优先级:浏览器默认设置<用户设置<外部样式<内联样式<HTML中的style样式;
3.将CSS与DOM合并,构建渲染树(Render Tree)
4.布局和绘制,重绘(repaint)和重排(reflow)
26.json和jsonp的区别
json返回的是一串json格式数据;而jsonp返回的是脚本代码
jsonp跨域的一种方式
原理:
因为浏览器有同源策略,所有ajax不能请求数据。但script标签不受同源策略的影响,所以通过动态创建script标签来加载服务器返回的数据,数据就是一个函数的调用
27.如何阻止冒泡
冒泡型事件:事件按照从最特定的事件目标到最不特定的事件目标(document对象)的顺序触发。
1.w3c的方法是e.stopPropagation()
2.IE则是使用e.cancelBubble = true
28.如何阻止默认事件
1.w3c的方法是e.preventDefault()
2.IE则是使用e.returnValue = false
29.JavaScript事件流模型都有什么
“事件冒泡”:事件开始由最具体的元素接受,然后逐级向上传播
“事件捕捉”:事件由最不具体的节点先接收,然后逐级向下,一直到最具体的
“DOM 事件流”:三个阶段:事件捕捉,目标阶段,事件冒泡
30.请你谈谈cookie的弊端
1.Cookie 数量和长度的限制。每个 domain 最多只能有 20 条 cookie,每个 cookie 长度 不能超过 4KB,否则会被截掉。
2.安全性问题。如果 cookie 被人拦截了,那人就可以取得所有的 session 信息。即使加密也与事无补,因为拦截者并不需要知道 cookie 的意义,他只要原样转发 cookie 就可以达到目的了。
3.有些状态不可能保存在客户端。
31.哪些操作会造成内存泄漏
- setTimeout 的第一个参数使用字符串而非函数的话,会引发内存泄漏。
- 闭包
- 控制台日志
- 循环(在两个对象彼此引用且彼此保留时,就会产生一个循环)
32.如何优化自己的代码
1.代码重用
2.避免全局变量(命名空间,封闭空间,模块化 mvc…)
3.拆分函数避免函数过于臃肿
33.解释 JavaScript 中的相等性
JavaScript 中有严格比较和类型转换比较:
- 严格比较(例如 ===)在不允许强制转型的情况下检查两个值是否相等;
- 抽象比较(例如 ==)在允许强制转型的情况下检查两个值是否相等。
34. 你能解释一下 ES5 和 ES6 之间的区别吗
- ECMAScript 5(ES5):ECMAScript 的第 5 版,于 2009 年标准化。这个标准已在所有现代浏览器中完全实现。
- ECMAScript 6(ES6)或 ECMAScript 2015(ES2015):第 6 版 ECMAScript,于 2015 年标准化。这个标准已在大多数现代浏览器中部分实现。
35.解释 JavaScript 中“undefined”和“not defined”之间的区别
- not defined一般会出现在控制台,提示错误:“xxx is not defined”表示xxxx没有被定义,是未定义的。
- undefined一般是表示JS中变量声明了如:var str;但是后续没有对其进行赋值就直接alert等进行输出操作,这时会提示undefined,即变量或者对象已经被定义但是没有被赋值所以不知道该变量用来做什么,此时console.log该变量会是undefined。
36.什么是 JavaScript 中的提升操作
提升(hoisting)是 JavaScript 解释器将所有变量和函数声明移动到当前作用域顶部的操作。有两种类型的提升:
- 变量提升——非常少见
- 函数提升——常见
无论 var(或函数声明)出现在作用域的什么地方,它都属于整个作用域,并且可以在该作用域内的任何地方访问它。
本文地址:https://blog.csdn.net/liu_kaige/article/details/109612356