第二篇 Javascript经典面试题+答案

1.dom结构操作怎么添加、移除、替换、插入、创建和查找节点?

添加:appendChild()
移除:removeChild()
替换:replaceChild()
插入:insertBefore()
创建节点:
1、创建一个dom片段:createDocumentFragment()
2、创建一个元素:createElement()
3、创建一个文本节点:createTextnode()
查找节点:
1、通过标签名称:getElementsByTagName()
2、通过元素的 Name 属性的值:getElementsByName()
3、通过元素 Id,唯一性:getElementById()

2.Javascript动画和CSS3动画有什么区别?

  • Javascript:
    优点:
    1、精细控制:可以通过改变属性值来实现对动画过程的精细控制,可实现css无法实现的动画效果,如动态的曲线运动,视差滚动等效果。
    2、交互性:可以在动画过程中获得数据响应,并实时调整。
    3、可以使用requestAnimationFrame浏览器Api解决丢帧,白屏问题。
    4、兼容性:绘制的动画基于dom,在操作上不存在兼容性问题,JavaScript动画能够在几乎所有浏览器上运行。
    缺点:
    1、重复的操作DOM元素的css样式,对浏览器性能消耗大,容易造成丢帧,白屏等情况。
    2、js动画只运行在主线程上,造成阻塞问题。
    3、实现复杂动画效果需要大量的逻辑与判断,复杂度高。
  • CSS3
    优点:
    1、性能高:CSS3动画通常使用GPU硬件加速,具有更好的性能表现。
    2、体验好:CSS3动画具有更好的动画体验,效果更加流畅。
    3、开发成本低:CSS3动画可以通过简单的CSS属性设置实现,开发成本较低。
    缺点:
    1、CSS3动画在一些旧版本的浏览器中不支持,需要额外编写代码兼容性
    2、CSS3动画的控制力度较低,无法实现对动画过程的精细控制。

3.DOM事件模型?

一个事件发生后,会在子元素和父元素之间传播。这种传播分为三个阶段:
W3C制定的机制标准为先捕获再冒泡。
1、捕获阶段
2、目标阶段
3、冒泡阶段

4.document.write和innerHTML的区别?

1、类型:document.write()是对象中的方法,innerHTML是element对象中的属性
2、插入位置:document.write()插入在执行该脚本元素的script标签位置,innerHTML插入在指定元素位置。
3、性能:document.write会重绘整个页面,而innerHTML可以重绘页面的某一部分

5.什么是重绘?什么是回流(重排)?如何减小化重绘和回流?

  • 回流:当Rendering Tree中部分元素的尺寸大小、布局、隐藏等属性改变时,浏览器的布局需要重新调整,需要重新渲染,这个过程就叫回流,也叫重排。(对整个页面进行排版)
  • 重绘:当元素属性的改变(比如元素字体颜色,背景颜色)不会影响浏览器的布局,针对这个样式进行重新绘制。
  • 减小化重绘和回流:
    1、避免逐次改变样式,样式统一批量修改。
    2、使DOM脱离文档流,再批量处理
    3、缓存布局属性
    4、 CSS3硬件加速:能够触发CSS3硬件加速的属性,彻底不会引起回流(transform、opacity、filters)

6.js脚本延迟加载的方式有哪些?

1、使用defer属性

 <script src="test2.js" defer></script>

2、使用async属性

 <script src="test2.js" async></script>

3、使用setTmeout属性
4、把js文件放在最后

7.什么是内存泄漏?

内存泄漏:是指程序动态分配的内存由于某种原因程序未释放或无法释放,造成系统内存的浪费,导致运行速度减慢或系统崩溃等。
常见的内存泄漏
1、意外的全局变量(变量未被定义或者胡乱引用了全局变量)
2、定时器(启动循环定时器后不清理)
3、闭包
4、事件监听未被移除
5、console.log(console.log对象是不能垃圾回收的)
6、缓存(建议所有缓存都设置过期时间,如果缓存过多也会造成内存泄漏)

8.什么是闭包?

闭包就是能够访问其他函数内部变量的函数

function fn(){
	var a = 1;
	function bar(){
		console.log(a);
	} 
	return bar;
}

var result =  fn();
result();

//解决内存泄漏
result = null;
fn = null

闭包的优点:可以访问函数内部的变量,并且不被全局污染,始终保存在内存中。
闭包的缺点:会使得函数中的变量始终保存在内存中,内存消耗大,所以不能滥用闭包,否则会造成页面性能问题,可能造成内存泄漏。

9.数组遍历的方式有哪些?性能如何?

1、for循环:所有循环遍历方法中性能最高的一种

for(i = 0,len=arr.length;i<len;i++){
}

2、forEach:性能比普通for循环弱

arr.forEach(function(e){  
});

3、map:返回一个新数组,性能比forEach循环弱

let result = arr.map((item,index)=>{
	if(index == 1) item = 2;
	return item;
})

4、reduce:通常用来求和

var arr = [1, 3, 5, 7, 9];
arr.reduce((x,y)=>{
	return x+y;
}) //25

5、filter:通过一些条件过滤一些数组的元素

var arr = [1, 2, 4, 5, 6, 9, 10, 15];
arr.filter((item)=>{
	return item%2 !== 0;
}) // // [1, 5, 9, 15]

6、some:用于检测数组元素是否有元素满足指定条件,有一个满足就会返回true,遇到满足指定条件的元素,就返回 true,剩余元素不再进行检测。对于空数组不会检测,直接返回false。

let arr = [2,4,6,8,10];
arr.some((item)=>{
    return item=2;
}) //true

7、every:用于检测数组元素是否都满足指定条件,若都满足才返回true,有一个不满足则返回false,剩余元素不再检测。对于空数组不会检测,直接返回true。

let arr = [2,4,6,8,10];
arr.every((item)=>{
    return item>0;
}) //true

10.js的继承方式?

1、原型链继承:通过b函数的原型(b.prototype)指向a的实例(new a())来实现
缺点:对象实例共享所有继承的属性和方法(父类共享),不能传参。

function Parent(){
    this.info = {
        name: 'a',
        age: 12
    }
}
Parent.prototype.getInfo= function(){
    console.log(this.info);
}

function Child() {}
Child.prototype = new Parent();

let c = new Child();
c.info.gender = "男";
c.getInfo(); //{name: 'a', age: 12, gender: '男'}

let c1 = new Child();
c1.getInfo(); //{name: 'a', age: 12, gender: '男'}

2、构造函数继承:在子类的构造函数内部调用父类的构造函数,使用call()将父对象的构造函数绑定在子对象上。
优点:解决了原形链继承中父类共享和不能传参的问题。
缺点:方法只能在构造函数中定义,无法实现函数复用,否则在父类原型上定义方法,在子类是不可见的。

function Parent(gender){
    this.info = {
        name: 'a',
        age: 12,
        gender:gender,
    }
}
function Child(gender) {
    Parent.call(this,gender)
}
let c1 = new Child('女');
c1.info; //{name: 'a', age: 12, gender: '女'}

3、组合式继承:将原型链和构造函数组合到一块,在原型上定义方法实现了函数复用,又能够保证每个实例都有自己的属性。
缺点: 无论在什么情况下,都会调用两次超类型构造函数:一次是在创建子类型原型的时候,另一次是在子类型构造函数内部。

function Parent(gender){
    this.info = {
        name: 'a',
        age: 12,
        gender:gender,
    }
}
Parent.prototype.getInfo=function(){
    console.log(this.info);
}
function Child(gender) {
    Parent.call(this,gender)
}
Child.prototype = new Parent();

let c1 = new Child('女');
c1.info.age=1
c1.getInfo(); //{name: 'a', age: 1, gender: '女'}

4、原型式继承
5、寄生式继承
6、寄生组合式继承
7、extends继承 (ES6)
不是所有的浏览器都支持class关键字

class Parent{
    constructor(){
        this.name = 'a';
        this.age = 12;
    }
}
class Child extends Parent{
    constructor(){
        super()
    }
}
let c = new Child()
c.name //'a'

11.改变函数内部this指针的指向函数(apply、call、bind的区别)?

如果不传参数,或者第一个参数时null或者undefined,默认this指向window

  • call:接受若干个参数,会立即执行函数。
foo.call(obj,1,2);
  • apply: 接受一个包含多个参数的数组,会立即执行函数。
foo.apply(obj,[1,2]);
  • bind:接受若干个参数,不会立即执行,会返回一个新函数,需要将函数再执行一遍。
let fn = foo.bind(obj,1,2);
fn();

12.new 操作符做了哪些事情?

1、创建一个空对象

var obj=new Object();

2、将空对象的原型_proto_ 指向构造函数的prototype

obj.__proto__= Func.prototype;

3、将构造函数的this指向自己

var result = Func.call(obj)

4、如果是值类型,返回该对象,如果是引用类型返回该引用类型的对象

return typeof(result == 'object'))? result:obj;

13.防抖和节流

  • 防抖:事件被触发n秒后再执行回调逻辑,如果在n秒内事件又被触发,则重新计算
    比如:input输入框、收藏和取消收藏
function debounce(){
	let timer = null;
	clearTimeout(timer);
	timer = seTimeout(()=>{
		func();
	},300)
}
  • 节流:事件以n秒为间隔执行回调逻辑。
    滚动事件
let timer = null
if(timer) return;
let timer = setTimeout(()=>{
	func();
	clearTimeout(timer);
	timer = null},300)

14.eval()函数是做什么的?

接受一个字符串的参数,并把这个参数作为脚本代码执行

eval('2+3') //5
eval('1>0?true:false') //true

15.深拷贝和浅拷贝?

浅拷贝:只是复制了原数据的内存地址,两个数据的指针指向了相同地址,其中任一个数据改变会影响另一个。
Object.assign()、扩展运算符、Array.from()数组的浅拷贝。
深拷贝:开辟了一个新的内存空间,数据发生改变时不会影响原数据。
JSON.stringify /parse、直接遍历push

16.数组常用方法?

push、pop、unshif、shif、splice、slice、sort、map、reduce、filter、some、every、concat、join(将数组的每一项用指定的字符连接成一个字符串)、reverse(颠倒数组元素顺序)、indexOf(检索值在第一次出现的位置索引)、includes(判断数组是否包含一个指定的值)

17.简单介绍一下symbol?

是一种基本数据类型,表示独一无二的值,可用于对象属性的命名。
除了作为对象属性名,Symbol 还可以用于实现类似于枚举类型的功能。
在es6之前,javascript对象的属性名只能以字符串类型,容易造成属性名冲突的问题,为了解决这个问题,es6引入Symbol类型。

let name = Symbol('id');
var bj = {
    [name]: 'a',
    age:10
}
console.log(bj) //{age: 10, Symbol(id): 'a'}

18.localstorage、sessionstorage和cookie的区别?

1、webstorage本地存储
webstorage是本地存储: localStorage (本地存储)和 sessionstorage(本地存储)。
存放数据一般为5MB,只在客户端中保存,不与服务器参与通信。
localStorage:永久存储数据,除非用户主动删除,否则数据一直存在。
sessionstorage:存储特定于某个会话的数据,也就是关闭浏览器数据就不存在了。
2、cookie
即HTTP Cookie,在HTTP请求发送Set-Cookie HTTP头作为响应的一部分。通过name=value的形式存储。(主要保存登录信息)
存放数据大小为4k左右,与服务器参与通信。
只在设置的cookie过期时间之前一直有效。如果不设置过期时间,则关闭浏览器就失效。

19.cookie、session、token?

20.{}和[] 的valueOf和toString的区别?

valueOf:偏向于运算
toString:偏向于显示

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值