2021前端JavaScript、ES6面试题归纳

JS、ES6篇

es6的新特性

  • const let
  • 模板字符串
  • 箭头函数
  • 函数的参数默认值
  • 对象和数组解构
  • for...of 和 for...in(for in更适合遍历对象,for of更适合遍历数组)

怎么用es5实现promise

Promise是ES6才引入的一个东西,他是一种异步编程的解决方案

if有作用域吗

只有函数有作用域,if是没有作用域的。

但是有一种情况会让if看上去有作用域,就是在if {}语句中,使用const、let,他们会有块级作用域。(因为const、let才拥有块级作用域 )

原型链和作用域链的区别

(1)原型链
当访问一个对象的某个属性时,会先在这个对象本身的属性上找,如果没有找到,会去这个属性的__proto__属性上找,即这个构造函数的prototype,如果还没找到,就会继续在__proto__上查找,
直到最顶层,找不到即为undefined。这样一层一层往上找,彷佛是一条链子串起来,所以叫做原型链。

(2)作用域链
变量取值会到创建这个变量的函数的作用域中取值,如果找不到,就会向上级作用域去查,直到查到全局作用域,这么一个查找过程形成的链条就叫做作用域链。

(3)区别
作用域是对变量而言,原型链是对于对象的属性而言
作用域链的顶层是window,原型链的顶层是Object

js判断类型

1、typeof
检测不出null 和 数组,结果都为object,所以typeof常用于检测基本类型

2、instanceof
不能检测出number、boolean、string、undefined、null、symbol类型,所以instancof常用于检测复杂类型以及级成关系

3、constructor
null、undefined没有construstor方法,因此constructor不能判断undefined和null。
但是contructor的指向是可以被改变,所以不安全

4、Object.prototype.toString.call
全类型都可以判断

数据类型怎么检测

1、typeof
例:console.log(typeof true) // boolean

2、instanceof
例:console.log([1,2] instanceof Array) // true

3、constructor
例: console.log([1, 2].constructor === Array) // ture

4、Object.prototype.toString.call
例:Object.prototype.toString.call([1, 2]) // [object Array]

普通函数和箭头函数的区别

1、普通函数
可以通过bind、call、apply改变this指向
可以使用new

2、箭头函数
本身没有this指向,
它的this在定义的时候继承自外层第一个普通函数的this
被继承的普通函数的this指向改变,箭头函数的this指向会跟着改变
箭头函数外层没有普通函数时,this指向window
不能通过bind、call、apply改变this指向
使用new调用箭头函数会报错,因为箭头函数没有constructor

如何用原生js给一个按钮绑定两个onclick事件?

var btn = document.getElementById('btn')
btn.addEventListener('click', fn1)
btn.addEventListener('click', fn2)

function fn1 () {
  console.log('我是方法1')  
}

function fn2 () {
  console.log('我是方法2')  
}

document.write和innerHTML的区别

document.write 将内容写入页面,清空替换掉原来的内容,会导致重绘

document.innerHTML 将内容写入某个Dom节点不会重绘

栈和堆的区别

1、堆
动态分配内存,内存大小不一,也不会自动释放

2、栈
自动分配相对固定大小的内存空间,并由系统自动释放

3、基本类型都是存储在栈中,每种类型的数据占用的空间的大小是确定的,并由系统自动分配和释放。内存可以及时回收。

4、引用类型的数据都是存储在堆中。准确说是栈中会存储这些数据的地址指针,并指向堆中的具体数据。

总的来说:里面存放的是基本数据类型(num string boolen null undefined),栈里面放的是引用数据类型(数组和对象)

 打个比方

2021前端JavaScript、ES6面试题归纳_第1张图片

[注] 栈内存入的是arr 是一个地址 堆内存入的是基本数据类型 

undefined 和 null 区别

1、null
什么都没有,表示一个空对象引用(主动释放一个变量引用的兑现那个,表示一个变量不再指向任何引用地址)
2、undefined
没有设置值的变量,会自动赋值undefined
3、区别
typeof undefined             // undefined
typeof null                  // object
null === undefined           // false
null == undefined            // true

eval()的作用

eval(string) 函数计算 JavaScript 字符串,并把它作为脚本代码来执行

如果参数是一个表达式,eval() 函数将执行表达式;

如果参数是Javascript语句,eval()将执行 Javascript 语句;

如果执行结果是一个值就返回,不是就返回undefined,如果参数不是一个字符串,则直接返回该参数。

特殊:eval("{b:2}") // 声明一个对象

        eval("({b:2})") // 返回对象{b:2}

JS哪些操作会造成内存泄露

内存泄漏是指一块被分配的内存既不能使用,也不能回收,直到浏览器进程结束。
1、意外的全局变量
2、闭包
3、没有清理的dom元素
dom元素赋值给变量,又通过removeChild移除dom元素。但是dom元素的引用还在内存中
4、被遗忘的定时器或者回调

谈谈垃圾回收机制方式及内存管理

JavaScript 在定义变量时就完成了内存分配。当不在使用变量了就会被回收,因为其开销比较大,垃圾收集器会定期(周期性)找出那些不再继续使用的变量,然后释放其内存。
(1)垃圾回收
标记清除法
当变量进入环境时,将这个变量标记为'进入环境'。当标记离开环境时,标记为‘离开环境’。离开环境的变量会被回收
引用技计数法
跟踪记录每个值被引用的次数,如果没有被引用,就会回收
(2)内存管理
内存分配=》内存使用=》内存回收

什么是闭包,如何使用它,为什么要使用它?

(1)闭包就是能够读取其它函数内部变量的函数
(2)使用方法:在一个函数内部创建另一个函数
(3)最大用处有两个:读取其他函数的变量值,让这些变量始终保存在内存中
(4)缺点:会引起内存泄漏(引用无法被销毁,一直存在)

请解释JSONP的工作原理,以及它为什么不是真正的AJAX

JSONP 是一种非正式传输协议,允许用户传递一个callback给服务端,然后服务端返回数据时会将这个callback 参数作为函数名来包裹住 JSON 数据,这样客户端就可以随意定制自己的函数来自动处理返回数据了。
当GET请求从后台页面返回时,可以返回一段JavaScript代码,这段代码会自动执行,可以用来负责调用后台页面中的一个callback函数。
它们的实质不同
ajax的核心是通过xmlHttpRequest获取非本页内容
jsonp的核心是动态添加script标签调用服务器提供的js脚本
jsonp只支持get请求,ajax支持get和post请求

请解释一下JavaScript的同源策略

同源指协议,域名,端口相同,
同源策略是一种安全协议,指一段脚本只能读取来自同一来源的窗口和文档的属性。

关于JS事件冒泡与JS事件代理(事件委托)

(1)事件冒泡
当一个元素接收到事件的时候 会把他接收到的事件传给自己的父级,一直到window,过程就像冒泡泡 。如果在某一层想要中止冒泡,使用 event.stopPropagation() 。
但是当大量标签大量事件的时候先然不可能为每个元素都加上事件,(事件绑定占用事件,浏览器要跟踪每个事件,占用更多内存。而且并不是所有事件都会被用户使用到)。所以需要事件委托来解决这个问题。
(2)事件委托
将事件给最外层的元素,自己不实现逻辑,由最外层元素来代理。(判断事件源,做不同处理)

new操作符到底做了什么

(1)var obj = new Fun()// 做了三件事

var obj  = {}  // 创建一个空对象
obj.__proto__ = Fun.prototype //空对象的__proto__指向构造函数的原型对象
Fun.call(obj) // 构造函数this指向替换成obj

(2)实现一个new
function _new(fn, ...arg) {
    const obj = Object.create(fn.prototype);
    const ret = fn.apply(obj, arg);
    // 根据规范,返回 null 和 undefined 不处理,依然返回obj,不能使用
    // typeof result === 'object' ? result : obj
    return ret instanceof Object ? ret : obj;
}

js延迟加载的方式有哪些?

(1)defer属性
        
        立即下载,但是会等到整个页面都解析完成之后再执行
(2)async属性
        
        不让页面等待脚本下载和执行(异步下载),但是无法控制加载的顺序
(3)动态创建script标签
(4)使用定时器延迟
(5)让js最后加载

promise、async有什么区别

1、什么是Async/Await
async/await是写异步代码的新方式,使用的方式看起来像同步
async/await是基于Promise实现的,它不能用于普通的回调函数。

2、什么是promise
为了解决异步嵌套而产生,让代码更易于理解

区别,async/await让代码更像同步,进一步优化了代码

== 和 ===的区别,什么情况下用相等==

”==” 是判断转换后的值是否相等, 

”===” 是判断值及类型是否完全相等

不需要判断类型时可以使用==

bind、call、apply的区别

let o1 = {
    a: 1
};
let o2 = {
    a: 2
};
let o3 = {
    a: 3
};

function fn(b, c) {
    console.log(this.a + b + c);
};

1、bind
var c = b.bind(o1, 2, 3); // 返回一个已经切换this指向的新函数
c(1,1)//依旧是6 因为bind指定this后不会再改变

2、apply
b.apply(a, [1, 1])  // 将b添加到a环境中
第一个参数是this指向的新环境
第二个参数是要传递给新环境的参数
注意: 第一个参数为null时表示指向window

3、call
b.call(a, 1, 1) // 将b添加到a环境中
第一个参数是this指向的新环境
第二、三...个参数是传递给新环境的参数
注意: 第一个参数为null时表示指向window

小结: bind方法可以让函数想什么时候调用就什么时候调用。apply、call方法只是临时改变了this指向。

call、apply区别

相同点:都是重定向this指针的方法。
不同点:call和apply的第二个参数不相同,call是若干个参数的列表。apply是一个数组

let mock = { value : 1 };
function mockNum(){
 console.log('value',this.value)
}
mockNum.call(mock) // 改变了函数中this的指向,当前this指向了mock对象

//转换一下实现方法就是

let mock = {
  value:1;
  mockNum:function(){
     console.log('value',this.value)
  }
}
mock.mockNum();
//所以经过上面这个操作的演化而来的结果就是如下步骤:
//1. 将函数设为一个对象的属性
//2. 并将这个函数的属性调用
//3. 删除该函数

Function.prototype.Mycall = function(context){
  let obj = context || window;
  obj.fn = this; //   这一步可以看做是this其实就指的当前函数。
  let args = [...arguments].slice(1); // 返回删除第一个元素的数组;
  let result = obj.fn(...args); // 调用函数
  delete obj.fn;
  return result;
}

// 操作一下
let mock = { value : 1 };
function mockNum(){
  console.log('value',this.value);
}
mockNum.Mycall(mock) // value 1



//apply的写法
Function.prototype.Myapply = function (context){
    let obj = context || window;
    obj.fn = this;
    let result = arguments[1] ? obj.fn(arguments[1]) : obj.fn([]);
    delete obj.fn;
    return result;
}
let mock3 = {
  arr: [1, 2, 3, 4, 5],
};
function arrx2(arr) {
  return this.arr.concat(arr).map((x) => x * 2);
}
console.log("arrx2", arrx2.myApply(mock3));

介绍暂时性死区

在代码块内,使用let、const命令声明变量之前,该变量都是不可用的。这在语法上,称为“暂时性死区”。

两个对象如何比较

有思路即可,步骤:
(1)判断两个类型是否对象
(2)判断两个对象key的长度是否一致
(3)判断属性value值的数据类型,根据不同数据类型做比较
    a、是对象,重复这个步骤
    b、是数组,转字符串比较
    c、是基本类型,直接判断

介绍各种异步方案

(1)回调函数
(2)promise
(3)async/await

Promise和Async处理失败的时候有什么区别

(1)Promise错误可以在构造体里面被捕获,而async/await返回的是promise,可以通过  catch直接捕获错误。
(2)await 后接的Promise.reject都必须被捕获,否则会中断执行

JS为什么要区分微任务和宏任务

(1)js是单线程的,但是分同步异步
(2)微任务和宏任务皆为异步任务,它们都属于一个队列
(3)宏任务一般是:script,setTimeout,setInterval、setImmediate
(4)微任务:原生Promise
(5)遇到微任务,先执行微任务,执行完后如果没有微任务,就执行下一个宏任务,如果有微任务,就按顺序一个一个执行微任务

Promise和setTimeout执行先后的区别

Promise是微任务,setTimeout是宏任务,先执行微任务,如有还有微任务执行完微任务再执行下一个宏任务

添加原生事件不移除为什么会内存泄露

2021前端JavaScript、ES6面试题归纳_第2张图片

setTimeout(0)和setTimeout(1)之间的区别

定时器表面意思是过指定时间后执行,但是真正的含义是每过指定时间后,会有fn进入事件队列
(1)setTimeout(fn,0)的含义是,指定某个任务在主线程最早可得的空闲时间执行,意思就是不用再等多少秒了,只要主线程执行栈内的同步任务全部执行完成,栈为空就马上执行
(2)setTimeout(fn,1) 1毫秒后执行,但是因为要先执行前面的宏任务,所以不一定就是在一毫秒后执行,取决于队列里任务执行的速度

for..in 和 object.keys的区别

Object.keys不会遍历继承的原型属性
for...in 会遍历继承的原型属性

XML和JSON的区别?

1.xml是重量级的,json是轻量级的。
2.xml在传输过程中比较占带宽,json占带宽少,易于压缩。
3.xml和json都用在项目交互下,xml多用于做配置文件,json用于数据交互。

说说你对AMD和Commonjs的理解

两者都是为了实现模块化编程而出现的
(1)commonjs
通常被应用于服务器,在服务器端,模块的加载和执行都在本地完成,因此,CommonJS并不要求模块加载的异步化。
核心思想:xsdz独文件就是一个模块,通过require方法来同步加载要依赖的模块,然后通过extports或则module.exports来导出需要暴露的接口。
(2)AMD
可以实现异步加载依赖模块,预加载,在并行加载js文件同时,还会解析执行该模块。虽然可以并行加载,异步处理,但是加载顺序不一定
(3)CMD
懒加载,虽然会一开始就并行加载js文件,但是不会执行,而是在需要的时候才执行。

js的涉及模式

单例模式、策略模式、代理模式、迭代器模式...等等

["1", "2", "3"].map(parseInt) 答案是多少?

(1)map用法:
arr.map(function(el, index, arr) {
    return el
})
map方法接收一个函数参数,并且这个函数可以接收三个参数
el:遍历过程中的当前项,
index:遍历过程中的当前下标
arr: 原数组

(2)parseInt用法:
parseInt(str, num)
根据num解析str,并返回一个整数。
str: 要解析的字符串,如果字符第一个数不能被转换,返回NaN。
num: 基数,介于 2 ~ 36 之间,如果传0,则默认用10计算。num不在区间内,返回NaN

(3)所以这道题,关键点就在num
el和index 相当于 str 和 num 带入一下
parseInt('1', 0) // '1' 用基数10算 为1
parseInt('2', 1) // NaN 1不在2-36内
parseInt('3', 2) // NaN  2进制内没有超过1的存在

常见兼容性问题?

(1)事件对象兼容
        e  = e || window.event;
(2)阻止事件冒泡兼容
        event.stopPropagation? event.stopPropagation():event.cancelBubble=true;
(3)阻止默认行为兼容
        evt.preventDefault?evt.preventDefault():evt.returnValue=false;
(4)事件监听兼容
        addEventListener  ? addEventListener  : attachEvent()
        removeEventListener() ? removeEventListener() : detachEvent()
(5)事件目标对象兼容
        var src = event.target || event.srcElement;

说说你对promise的了解

(1)promise是为解决异步处理回调金字塔问题而产生的
(2)有三种状态,pengding、resolve、reject,状态一旦决定就不会改变
(3)then接收resolve(),catch接收reject()

介绍js有哪些内置对象?

String对象、Array对象、Object对象、Number对象
Math对象、Date对象、Boolean对象

说几条写JavaScript的基本规范?

1、不要在同一行声明多个变量
2、使用 === 和 !== 来比较
3、不要使用全局函数
4、变量在使用之前的位置声明(减少变量提升干扰)
5、if用花括号包起来即使只有一行
6、写注释

JavaScript有几种类型的值?,你能画一下他们的内存图吗?

栈:原始数据类型(Undefined  Null  Boolean  Number  String)
堆:引用数据类型(对象、数组、函数)

2021前端JavaScript、ES6面试题归纳_第3张图片

href="#"与href="javascript:void(0)的区别"?

1、# 包含了一个位置信息,默认的锚是#top 也就是网页的上端。在页面很长的时候会使用 # 来定位页面的具体位置,格式为:# + id。

2、javascript:void(0), 仅仅表示一个死链接。

如果你要定义一个死链接请使用 javascript:void(0) 

对this的理解

1、单独使用,this表示全局对象
2、在函数中,this表示全局对象
3、在对象的一个函数方法中,this表示这个对象
4、可以通过apply、bind来更改this的指向

ps: this永远指向的是最后调用它的对象,仅当它在对象的一个函数方法中时会有差异

promise.all 返回什么

如果没有报错,返回执行结果[res1, res2,...]
如果报错,则返回第一个报错的promise的结果

多个await的执行顺序,如果要同步执行如何实现?

使用Promise.all
promise.all是等所有异步操作都完成之后返回结果,相当于让这些异步同步了

 拖拽会用到哪些事件

  • dragstart:拖拽开始时在被拖拽元素上触发此事件,监听器需要设置拖拽所需数据,从操作系统拖拽文件到浏览器时不触发此事件.
  • dragenter:拖拽鼠标进入元素时在该元素上触发,用于给拖放元素设置视觉反馈,如高亮
  • dragover:拖拽时鼠标在目标元素上移动时触发.监听器通过阻止浏览器默认行为设置元素为可拖放元素.
  • dragleave:拖拽时鼠标移出目标元素时在目标元素上触发.此时监听器可以取消掉前面设置的视觉效果.
  • drag:拖拽期间在被拖拽元素上连续触发
  • drop:鼠标在拖放目标上释放时,在拖放目标上触发.此时监听器需要收集数据并且执行所需操作.如果是从操作系统拖放文件到浏览器,需要取消浏览器默认行为.
  • dragend:鼠标在拖放目标上释放时,在拖拽元素上触发.将元素从浏览器拖放到操作系统时不会触发此事件. 

请列举jquery中的选择器

#id,.class,element,:first,:even,:eq(index),:contains(text)

注:这些选择器都是基于$()的

Javascript中的定时器有哪些?他们的区别及用法是什么?

setTimeout 只执行一次
setInterval 会一直重复执行

请描述一下 cookies sessionStorage和localstorage区别

2021前端JavaScript、ES6面试题归纳_第4张图片

编写一个方法去掉数组里面重复的内容

var arr=['abc','abcd','sss','2','d','t','2','ss','f','22','d']
//定义一个新的数组
var s=[]
//遍历数组
for(var i=0;i

什么是ajax? ajax的步骤?

ajax(异步javascript xml) 能够刷新局部网页数据而不是重新加载整个网页。
如何使用ajax?
第一步,创建xmlhttprequest对象

var xmlhttp =new XMLHttpRequest();
//XMLHttpRequest对象用来和服务器交换数据。
var xhttp;
if (window.XMLHttpRequest) {
//现代主流浏览器
xhttp = new XMLHttpRequest();
} else {
// 针对浏览器,比如IE5或IE6
xhttp = new ActiveXObject("Microsoft.XMLHTTP");
}

第二步,使用xmlhttprequest对象的open()和send()方法发送资源请求给服务器。
第三步,使用xmlhttprequest对象的responseText或responseXML属性获得服务器的响应。
第四步,onreadystatechange函数,当发送请求到服务器,我们想要服务器响应执行一些功能就需要使用onreadystatechange函数,每次xmlhttprequest对象的readyState发生改变都会触发onreadystatechange函数。

http和https有何区别?

http是HTTP协议运行在TCP之上。所有传输的内容都是明文,客户端和服务器端都无法验证对方的身份。
https是HTTP运行在SSL/TLS之上,SSL/TLS运行在TCP之上。所有传输的内容都经过加密,
加密采用对称加密,但对称加密的密钥用服务器方的证书进行了非对称加密。
此外客户端可以验证服务器端的身份,如果配置了客户端验证,服务器方也可以验证客户端的身份。

常见的HTTP状态码 

2开头 (请求成功)表示成功处理了请求的状态代码。
200   (成功)  服务器已成功处理了请求。 通常,这表示服务器提供了请求的网页。
201   (已创建)  请求成功并且服务器创建了新的资源。
202   (已接受)  服务器已接受请求,但尚未处理。
203   (非授权信息)  服务器已成功处理了请求,但返回的信息可能来自另一来源。
204   (无内容)  服务器成功处理了请求,但没有返回任何内容。
205   (重置内容) 服务器成功处理了请求,但没有返回任何内容。
206   (部分内容)  服务器成功处理了部分 GET 请求。


3开头 (请求被重定向)表示要完成请求,需要进一步操作。 通常,这些状态代码用来重定向。
300   (多种选择)  针对请求,服务器可执行多种操作。 服务器可根据请求者 (user agent) 选择一项操作,或提供操作列表供请求者选择。
301   (永久移动)  请求的网页已永久移动到新位置。 服务器返回此响应(对 GET 或 HEAD 请求的响应)时,会自动将请求者转到新位置。
302   (临时移动)  服务器目前从不同位置的网页响应请求,但请求者应继续使用原有位置来进行以后的请求。
303   (查看其他位置) 请求者应当对不同的位置使用单独的 GET 请求来检索响应时,服务器返回此代码。
304   (未修改) 自从上次请求后,请求的网页未修改过。 服务器返回此响应时,不会返回网页内容。
305   (使用代理) 请求者只能使用代理访问请求的网页。 如果服务器返回此响应,还表示请求者应使用代理。
307   (临时重定向)  服务器目前从不同位置的网页响应请求,但请求者应继续使用原有位置来进行以后的请求。


4开头 (请求错误)这些状态代码表示请求可能出错,妨碍了服务器的处理。
400   (错误请求) 服务器不理解请求的语法。
401   (未授权) 请求要求身份验证。 对于需要登录的网页,服务器可能返回此响应。
403   (禁止) 服务器拒绝请求。
404   (未找到) 服务器找不到请求的网页。
405   (方法禁用) 禁用请求中指定的方法。
406   (不接受) 无法使用请求的内容特性响应请求的网页。
407   (需要代理授权) 此状态代码与 401(未授权)类似,但指定请求者应当授权使用代理。
408   (请求超时)  服务器等候请求时发生超时。
409   (冲突)  服务器在完成请求时发生冲突。 服务器必须在响应中包含有关冲突的信息。
410   (已删除)  如果请求的资源已永久删除,服务器就会返回此响应。
411   (需要有效长度) 服务器不接受不含有效内容长度标头字段的请求。
412   (未满足前提条件) 服务器未满足请求者在请求中设置的其中一个前提条件。
413   (请求实体过大) 服务器无法处理请求,因为请求实体过大,超出服务器的处理能力。
414   (请求的 URI 过长) 请求的 URI(通常为网址)过长,服务器无法处理。
415   (不支持的媒体类型) 请求的格式不受请求页面的支持。
416   (请求范围不符合要求) 如果页面无法提供请求的范围,则服务器会返回此状态代码。
417   (未满足期望值) 服务器未满足"期望"请求标头字段的要求。


5开头(服务器错误)这些状态代码表示服务器在尝试处理请求时发生内部错误。 这些错误可能是服务器本身的错误,而不是请求出错。
500   (服务器内部错误)  服务器遇到错误,无法完成请求。
501   (尚未实施) 服务器不具备完成请求的功能。 例如,服务器无法识别请求方法时可能会返回此代码。
502   (错误网关) 服务器作为网关或代理,从上游服务器收到无效响应。
503   (服务不可用) 服务器目前无法使用(由于超载或停机维护)。 通常,这只是暂时状态。
504   (网关超时)  服务器作为网关或代理,但是没有及时从上游服务器收到请求。
505   (HTTP 版本不受支持) 服务器不支持请求中所用的 HTTP 协议版本。

如何进行网站性能优化

(1)目的: 从用户角度而言,优化能够让页面加载得更快、对用户的操作响应得更及时,能够给用户提供更为友好的体验。从服务商角度而言,优化能够减少页面请求数、或者减小请求所占带宽,能够节省可观的资源。

(2)措施:

——减少HTTP请求数。
——使用缓存。
——脚本的无阻塞加载。
——内联脚本的位置优化等。
——Javascript中的DOM 操作优化、CSS选择符优化。
——图片编码优化,懒加载。
——使用负载均衡方案。

什么是mvvm,mvc?区别?

MVC(Model-View-Controller)

MVC是比较直观的架构模式,用户操作
 ->View(负责接收用户的输入操作)
 ->Controller(业务逻辑处理)->Model(数据持久化)->View(将结果反馈给View)。             MVC使用非常广泛,比如JavaEE中的SSH框架。

MVVM(Model-View-ViewModel)

->Model:数据层

->View:视图层

->ViewModel:数据视觉层

px和em的区别

px表示像素 (计算机屏幕上的一个点:1px = 1/96in),是绝对单位,不会因为其他元素的尺寸变化而变化;
em表示相对于父元素的字体大小。em是相对单位 ,没有一个固定的度量值,而是由其他元素尺寸来决定的相对值。

优雅降级和渐进增强

渐进增强(Progressive Enhancement):一开始就针对低版本浏览器进行构建页面,完成基本的功能,然后再针对高级浏览器进行效果、交互、追加功能达到更好的体验。
优雅降级(Graceful Degradation):一开始就构建站点的完整功能,然后针对浏览器测试和修复。比如一开始使用 CSS3 的特性构建了一个应用,然后逐步针对各大浏览器进行 hack 使其可以在低版本浏览器上正常浏览。

其实渐进增强和优雅降级并非什么新概念,只是旧的概念换了一个新的说法。在传统软件开发中,经常会提到向上兼容和向下兼容的概念。渐进增强相当于向上兼容,而优雅降级相当于向下兼容。

怎样添加、移除、移动、复制、创建和查找节点?

(1)创建新节点

createDocumentFragment() //创建一个DOM片段

createElement() //创建一个具体的元素

createTextNode() //创建一个文本节点

(2)添加、移除、替换、插入

appendChild() //添加

removeChild() //移除

replaceChild() //替换

insertBefore() //插入

(3)查找

getElementsByTagName() //通过标签名称

getElementsByName() //通过元素的Name属性的值

getElementById() //通过元素Id,唯一性

浏览器是如何渲染页面的?

1.解析HTML文件,创建DOM树。
  自上而下,遇到任何样式(link、style)与脚本(script)都会阻塞(外部样式不阻塞后续外部脚本的加载)。
2.解析CSS。优先级:浏览器默认设置<用户设置<外部样式<内联样式

从输入url到显示页面,都经历了什么?

1、首先,在浏览器地址栏中输入url。
2、浏览器先查看浏览器缓存-系统缓存-路由器缓存,如果缓存中有,会直接在屏幕中显示页面内容。若没有,则跳到第三步操作。
3、在发送http请求前,需要域名解析(DNS解析)(DNS(域名系统,Domain Name System)是互联网的一项核心服务,它作为可以将域名和IP地址相互映射的一个分布式数据库,能够使人更方便的访问互联网,而不用去记住IP地址。),解析获取相应的IP地址。
4、浏览器向服务器发起tcp连接,与浏览器建立tcp三次握手。(TCP即传输控制协议。TCP连接是互联网连接协议集的一种。)
5、握手成功后,浏览器向服务器发送http请求,请求数据包。
6、服务器处理收到的请求,将数据返回至浏览器。
7、浏览器收到HTTP响应。
8、读取页面内容,浏览器渲染,解析html源码。
9、生成Dom树、解析css样式、js交互。
10、客户端和服务器交互。
11、ajax查询。

JavaScript中如何检测一个变量是一个String类型?请写出函数实现

typeof(obj) === "string"
typeof obj === "string"
obj.constructor === String

判断一个字符串中出现次数最多的字符,统计这个次数

    function aa() {
        let str = 'asdfssaaasasasasaa';
        let json = {};
        for (let i = 0; i < str.length; i++) {
            let index = str[i]
            if (!json[index]) {
                json[index] = 1
            } else {
                json[index]++
            }
        }
        let iMax = 0
        let iIndex = ''
        for(let k in json){
            if(json[k]>iMax){
                iMax =json[k]
                iIndex=k
            }
        }
        console.log('出现次数最多的是:' + iIndex + '出现' + iMax + '次');

$(document).ready()方法和window.onload有什么区别?

(1)、window.onload方法是在网页中所有的元素(包括元素的所有关联文件)完全加载到浏览器后才执行的。
(2)、$(document).ready() 方法可以在DOM载入就绪时就对其进行操纵,并调用执行绑定的函数。

window.onLoad和DOMContentLoaded事件的先后顺序?

顺序

一般情况下,DOMContentLoaded事件要在window.onload之前执行,当DOM树构建完成的时候就会执行 DOMContentLoaded事件,而window.onload是在页面载入完成的时候,才执行

区别

1、当 onload事件触发时,页面上所有的DOM,样式表,脚本,图片,flash都已经加载完成了。

2、当DOMContentLoaded事件触发时,仅当DOM加载完成,不包括样式表,图片,flash。

JavaScript中的变量声明提升?

函数声明和变量声明总是被JavaScript解释器隐式地提升到包含他们的作用域的最顶端。

function优先声明于var。

函数表达式中只会提升名称,函数体只有在执行到赋值语句时才会被赋值。

function foo() {
     bar(); 
     var x = 1; 
} 
function foo() {//等同于
   var x;
   bar(); 
   x = 1; 
} 
function test() { 
    foo(); // TypeError "foo is not a function" 
    bar(); // "this will run!"
    var foo = function () {}// 函数表达式被赋值给变量'foo' 
    function bar() {}// 名为'bar'的函数声明 
}

请写出console.log中的内容

    var msg = 'hello';//顶级作用域window下有个变量msg
    function great(name, attr) {
        var name = 'david';
        var greating = msg + name + '!';
        var msg = '你好';
        for (var i = 0; i < 10; i++) {
            var next = msg + '你的id是' + i * 2 + i;
        }
        console.log(arguments[0]);//david
        console.log(arguments[1]);//undefind
        console.log(greating);//undefineddavid!
        console.log(next);//你好你的id是189
    }

    great('Tom')

注:在作用域内会先调用作用域内的变量,如果var变量在声明之前就使用了就是变量提升是undefined

JS延迟加载的方式有哪些?

1、 JS的延迟加载有助与提高页面的加载速度。

2、 defer 和async 、动态创建DOM 方式(用得最多)、按需异步载入

3、 JSdefer:延迟脚本。立即下载,但延迟执行(延迟到整个页面都解析完毕后再运行),按照脚本出现的先后顺序执行。

4、 async :异步脚本。下载完立即执行,但不保证按照脚本出现的先后顺序执行。

为什么避免v-if和v-for一起使用

当 v-if 与 v-for 一起使用时,v-for 具有比 v-if 更高的优先级;
可以先对数据在计算数据中进行过滤,然后再进行遍历渲染;
操作和实现起来都没有什么问题,页面也会正常展示。但是会带来不必要的性能消耗;

深拷贝和浅拷贝的方法

浅拷贝  Object.assign()    //es6的方法

var obj={aa:1,b:{item:'45'}};
var newObj=Object.assign({},obj);
obj.aa=2;
obj.b.item='kk';
console.log(newObj.aa);        //1
console.log(newObj.b.item);    //kk

深拷贝  JSON.parse(JSON.stringify(obj))

  function cloneDeep(source) {
      if (!isObject(source)) return source; // 非对象返回自身
      var target = Array.isArray(source) ? [] : {};
      for (var key in source) {
        if (source.hasOwnProperty(i)) {
          if (isObject(source[key])) {
            target[key] = cloneDeep(source[key]); // 注意这里
          } else {
            target[key] = source[key];
          }
        }
      }
      return target;
    }
    function isObject(obj) {
      return typeof obj === 'object' && obj != null;
    }

如何统计网⻚上出现了多少种标签 

获取所有的DOM节点

document.querySelectorAll('*')

NodeList集合转化为数组

[...document.querySelectorAll('*')]

获取数组每个元素的标签名 

[...document.querySelectorAll('*')}.map(ele => ele.tagName)

去重

new Set([...document.querySelectorAll('*').map(ele=>ele.tagName)).size

你可能感兴趣的:(javascript,node.js,面试)