当前位置: 首页>后端>正文

原生js面试题一

1.Promise

Promise是异步编程的一种解决方案,从语法上讲,Promise是一个对象,可以获取异步操作的消息
目的: (1)、避免回调地狱的问题(2)、Promise对象提供了简洁的API,使得控制异步操作更加容易
Promise有三种状态:pendding //正在请求,rejected //失败,resolved //成功
Promise的用法:

是一个构造函数,这个构造函数里有两个参数,分别是:resolve(成功之后的回调函数)、reject(失败之后的回调函数)。

因为promise表示的是一个异步操作,每当我们new一个promise实例,就表示一个具体的异步操作,那么这个异步操作的结果就只能有两种状态:成功/失败,两者都需要回调函数resolve/reject返回。所以内部拿到操作的结果后,无法使用return把操作结果返回给调用者,这时候只能用回调函数的形式来把成功或失败的结果返回给调用者

2.var let const的区别

var是ES5提出的,let和const是ES6提出的。

const声明的是常量,必须赋值
1)一旦声明必须赋值,不能使用null占位。
2)声明后不能再修改
3)如果声明的是复合类型数据,可以修改其属性

let和var声明的是变量,声明之后可以更改,声明时可以不赋值

var允许重复声明变量,后一个变量会覆盖前一个变量。let和const在同一作用域不允许重复声明变量,会报错。

var声明的变量存在变量提升(将变量提升到当前作用域的顶部)。即变量可以在声明之前调用,值为undefined。
let和const不存在变量提升。即它们所声明的变量一定要在声明后使用,否则报ReferenceError错。
Ruan fu run si ai we
var不存在块级作用域。let和const存在块级作用域。
ES5中作用域有:全局作用域、函数作用域。没有块作用域的概念。
ES6(简称ES6)中新增了块级作用域。块作用域由 { } 包括,if语句和for语句里面的{ }也属于块作用域。

3.跨 域

概念:只要协议、域名、端口有任何一个不同,都被当作是不同的域。

跨域可以简单的理解为从一个域名访问另一个域名,出于安全考虑,浏览器不允许这么 做。

同源策略:所谓的同源策略指的是浏览器出于安全的考虑 要求用户访问的文件必须 满足三个条件:

1: 主机地址相同

2: 协议相同

3: 端口号相同

this 指向函数运行时所属的对象

              this 不指函数本身,也不指函数所对的作用域,指向调用此函数的对象 

4.this 指向分为六种情况

1) 全局函数中的this,在全局环境下调用的时候指向window

注意:如果全局函数内部是严格模式,则在全局环境下不指向window 指undefined

2) 函数被赋值给某个事件时,指向对象所属的对象

3) this在对象的方法中使用时,指向的是 方法所属的对象

4)在闭包中 this 指向window

5) 在构造函数中以及构造函数的原型对象中的this,都指向构造函数的实例对象
var arr=new Array() Array 是构造函数 arr 实例对象

6)箭头函数中的this 指向 箭头函数被定义的执行环境

5.作用域闭包

闭包是一个能够读取其他函数内部数据(变量和函数)的函数,在js语言中,只有函数内部的子函数才能访问到该函数的局部变量,所以也可以把闭包理解成一个函数中的函数

闭包的好处
可以读取其他函数中的变量
可以将这些变量的值始终保存到内存中
//延长作用域链// 处理变量不能及时传递的问题// 生成预编译函数

闭包有什么坏处

  1. 增加了内存的消耗。

  2. 某些浏览器上因为回收机制的问题,有内存泄漏,内存溢出风险。

  3. 增加了代码的复杂度,维护和调试不便。

内存泄漏

什么情况会产生内存泄漏

1)意外的全局变量
2)计时器没有及时清除
3)使用不当的闭包函数
4)遗漏的DOM元素
改变this指向的方法

通过call() apply() bind()

call方法:var o=obj.fn().call(obj);

apply方法:var o=obj.fn().apply(obj);

try catch finally

处理代码中可能出现的错误信息

try 放置测试错误的代码块

catch放置当try的代码发生错误时,所执行的代码

finally在try和catch有无异常时都会处理的代码

throw 抛出错误 一般在try中使用 错误信息是自定义的

6.面向对象

对象是带有属性和方法的特殊数据类型

属性是与对象相关的值
方法是能够在对象上执行的动作
什么是面向对象
将所需要做的功能抽象成一个对象 然后反复调用这个对象来完成你想要的功能

7.new做了哪些事情new的作用

1)实例的时候会创建一个新的空对象

2)会将this 指向 空对象

3) 会将绑定给this的属性和方法 设置给空对象

4)最后会将对象返出

8.jQuery概念:

jQuery是一个快速,小且功能丰富的JavaScript库。它使HTML文档的遍历和操作,事件处理,动画和Ajax等操作变得更加简单,它提供了一个易于使用的API,可以跨多种浏览器工作(兼容性比较好)

1.特点:
(1)轻量级,体积小,使用灵巧(只要引入一个JS文件)
(2)强大的选择器
(3)出色的DOM操作
(4)出色的浏览器兼容性
(5)可靠的事件处理机制
(6)完善的Ajax
(7)链式操作方式
(8)丰富的插件支持
(9)完善的文档
(10)开源
9.同步异步

同步:提交请求->等待服务器处理->处理完毕返回 这个期间客户端浏览器不能 干任何事
缺点:容易导致代码阻塞
优点:程序员容易理解(因为代码从上往下一行行执行,强调顺序)
异步: 请求通过事件触发->服务器处理(这时浏览器仍然可以作其他事情)-> 处理完毕
缺点:程序员不易理解(因为不是按顺序执行的)
优点:可以解决代码阻塞问题,提升代码执行效率和性能

10.什么是深拷贝和浅拷贝

· 浅拷贝是创建一个新对象,这个对象有着原始对象属性值的一份精确拷贝。如果属性是基本类型,拷贝的就是基本类型的值,如果属性是引用类型,拷贝的就是内存地址 ,所以如果其中一个对象改变了这个地址,就会影响到另一个对象。

· · 深拷贝是将一个对象从内存中完整的拷贝一份出来,从堆内存中开辟一个新的区域存放新对象,且修改新对象不会影响原对象。

11.谈谈this的理解

1)this总是指向函数的直接调用者(而非间接调用者)
2)如果有new关键字,this指向new出来的那个对象
3)在事件中,this指向目标元素,特殊的是IE的attachEvent中的this总是指向全局对象window

12.什么是跨域问题,如何解决跨域问题?

因为浏览器有同源策略,如果协议(http或者https)不同、端口不同、主机不同,三者满足其一即产生跨域,跨域的解决方案最优的是cors

13.Call apply bind区别

call,apply,bind主要作用都是改变this指向的,说一下区别:
call和apply的主要区别是在传递参数上不同,call后面传递的参数是以逗号的形式分开的,
apply传递的参数是数组形式 [Apply是以A开头的,所以应该是跟Array(数组)形式的参数]
bind返回的是一个函数形式,如果要执行,则后面要再加一个小括号 例如:bind(obj,参数1,
参数2,)(),bind只能以逗号分隔形式,不能是数组形式

14.防抖和节流

防抖: 在事件被触发n秒后再执行回调,如果在这n秒内又被触发,则重新计时。
防抖 一般用在轮播图
思路:每次触发事件时都取消之前的延时调用方法
节流: 规定在一个单位时间内,只能触发一次函数。如果这个单位时间内触发多次函数,只有一次生效

获取滚动条去上面的距离,窗口大小改变
思路:每次触发事件时都判断当前是否有等待执行的延时函数

15.原型和原型链的理解

每个构造函数都有一个prototype属性,这个属性会指向他的原型对象,
每个实例化的对象都会有proto属性,这个属性会指向改对象的原型,
每个原型都有constactor属性,指向关联的构造函数

当读取实例对象的属性时,会先去内部找,找不到就去关联的原型对象中找,还没有就会一直往上找原型对象的原型,知道最顶层的Object.prototype,如果他的proto属性为null,那么最终会返回undefined
这样层层递进就形成了实例予原型之间的链式关系,就是原型链

16.什么是Typescript?

TypeScript是一种由微软开发和维护的免费开源编程语言。它是一个强类型的JavaScript超集,可编译为纯JavaScript。它是一种用于应用级JavaScript开发的语言。对于熟悉c#、Java和所有强类型语言的开发人员来说,TypeScript非常容易学习和使用。
TypeScript可以在任何浏览器、主机和操作系统上执行。TypeScript不是直接在浏览器上运行的。它需要一个编译器来编译和生成JavaScript文件。TypeScript是带有一些附加特性的ES6 JavaScript版本。

17.宏任务和微任务的意义区别

宏任务是能够在宿主环境的协助下,通过回调队列来完成异步操作,
微任务则是在宏任务执行前,进行某些操作,告诉 Javascript 引擎在处理完当前执行队列后,尽快地执行我们的代码。

宏任务
1.setTimeout
2.setInterval
微任务
1.Promise
2.MutationObserver

18.怎么解决跨域问题

JSONP跨域
jsonp的原理就是利用<script>标签没有跨域限制,通过<script>标签src属性,发送带有callback参数的GET请求,服务端将接口返回数据拼凑到callback函数中,返回给浏览器,浏览器解析执行,从而前端拿到callback函数返回的数据。
是代理(前端代理和后端代理)前端代理我在vue中主要是通过vue脚手架中的config中的index文件来配置的,其中
有个proxyTable来配置跨域的
跨域是前后端分离下常常会遇到的问题,我们可以通过在vue.config.js文件中配置proxy项来解决
module.exports = {
outputDir: 'dist', //build输出目录
assetsDir: 'assets', //静态资源目录(js, css, img)
lintOnSave: false, //是否开启eslint
devServer: {
open: true, //是否自动弹出浏览器页面
host: "localhost",
port: '8080', //我的端口
}
}
proxy: {
'/api': {
target: 'http://localhost:8888', //后端服务器地址
ws: true, //代理websockets
changeOrigin: true, // 虚拟的站点需要更管origin
pathRewrite: {//重写路径
'^/api': ''
}
}
},
CORS
CORS全称叫跨域资源共享,主要是后台工程师设置后端代码来达到前端跨域请求的
注:现在主流框架都是用代理和CORS跨域实现的

Vue axios实现
this.原生js面试题一,http = axios; this.,第1张http.jsonp('http://www.domain2.com:8080/login', {
params: {},
jsonp: 'handleCallback'
}).then((res) =>
{ console.log(res); })

Ajax 实现
$.ajax({ url: 'http://www.domain2.com:8080/login',
type: 'get',
dataType: 'jsonp',// 请求方式为
jsonp jsonpCallback: "handleCallback",// 自定义回调函数名
data: {}
});

19.原型和原型链是什么

原型
js中 万物皆对象 每一个对象都有自己的属性
js中每一个对象都有一个与他关联的对象 叫做原型对象
每次获取原型对象属性都是一次查询的过程 在对象的自有属性中找不到就会去查找它的原型对象
原型链
原型连成一条链 JS在查找属性过程中 如果在自有属性中找不到就会去原型对象中查找 如果原型对象中找不到 就回去原型对象的原型中查找 也就是按照原型链查找直到查找到原型链的顶端 Object

20.作用域&作用域链

JS作用域也就是JS识别变量的范围,作用域链也就是JS查找变量的顺序
先说作用域,JS作用域主要包括全局作用域、局部作用域和ES6的块级作用域
全局作用域:也就是定义在window下的变量范围,在任何地方都可以访问,
局部作用域:是只在函数内部定义的变量范围
块级作用域:简单来说用let和const在任意的代码块中定义的变量都认为是块级作用域中的变
量,例如在for循环中用let定义的变量,在if语句中用let定义的变量等等
注:尽量不要使用全局变量,因为容易导致全局的污染,命名冲突,对bug查找不利。
2而
所谓的作用域链就是由最内部的作用域往最外部,查找变量的过程.形成的链条就是作用域链

21.HTML5新特性

HTML5 将成为 HTML、XHTML 以及 HTML DOM 的新标准

1)用于绘画的 canvas 元素

(2)用于媒介回放的 video 和 audio 元素

(3)对本地离线存储的更好的支持

(4)新的特殊内容元素,比如 article、footer、header、nav、section

(5)新的表单控件,比如 calendar、date、time、email、url、search

22. 说?下JS数组内置遍历?法有哪些和区别

JS数组内置遍历(遍历就是循环的意思)方法主要有:
forEach:这个方法是为了取代for循环遍历数组的,返回值为undefined例如:
let arrInfo=[4,6,6,8,5,7,87]
arrInfo.forEach((item,index,arr)=>{
//遍历逻辑
})
其中:
item代码遍历的每一项,
index:代表遍历的每项的索引,
arr代表数组本身
filter:是一个过滤遍历的方法,如果返回条件为true,则返回满足条件为true的新数组
let arrInfo=[4,16,6,8,45,7,87]
let resultArr=arrInfo.filter((item,index,arr)=>{
//例如返回数组每项值大于9的数组
return item>9
})
map:这个map方法主要对数组的复杂逻辑处理时用的多,特别是react中遍历数据,也经常用 到,写法和forEach类似some:这个some方法用于只要数组中至少存在一个满足条件的结果,返回值就为true,否则返回
fasel, 写法和forEach类似
every:这个every方法用于数组中每一项都得满足条件时,才返回true,否则返回false, 写法 和forEach类似

23. 说?下从输?URL到??加载完中间发?了什么?

大致过程是这样的:

  1. DNS解析
  2. TCP连接
  3. 发送HTTP请求
  4. 服务器处理请求并返回需要的数据
  5. 浏览器解析渲染页面
  6. 连接结束
    输入了一个域名,域名要通过DNS解析找到这个域名对应的服务器地址(ip),通过TCP请求链接服务,通过 WEB服务器(apache)返回数据,浏览器根据返回数据构建DOM树,通过css渲染引擎及js解析引擎将页面渲染出 来,关闭tcp连接

24.说?下JS事件代理(也称事件委托)是什么

JS事件代理就是通过给父级元素(例如:ul)绑定事件,不给子级元素(例如:li)绑定事
件,然后当点击子级元素时,通过事件冒泡机制在其绑定的父元素上触发事件处理函数,主要目的
是为了提升性能,因为我不用给每个子级元素绑定事件,只给父级元素绑定一次就好了,在原生js里
面是通过event对象的targe属性实现

25. 深拷?,浅拷?

?es6的Object.assign({},{})进行对象合并,如果是数组可以用es6的
Array.from,或是es6的扩展运算符...arr,如果使?es5需要?循环来做
浅拷贝,
如果是深拷贝需要?递归的形式来实现.当然也可以使用
JSON.parse(JSON.stringify(对象))的方式实现深拷贝

浅拷贝:一般指的是把对象的第一层拷贝到一个新对象上去
深拷贝:一般需要借助递归实现,如果对象的值还是个对象,要进一步的深入拷贝,完全替换掉每一个复杂类型的引用

26.Promise和async await 的区别

Promise,简单来说就是一个容器,里面保存着某个未来才会结束的时间(通常是一个异步操作的结果)

async、await将异步强行转换为同步处理。async/await与promise不存在谁代替谁的说法,因为async/await是寄生于Promise,Generater的语法糖。

1 promise是ES6,async/await是ES7
2 async/await相对于promise来讲,写法更加优雅
3 reject状态:
1)promise错误可以通过catch来捕捉,建议尾部捕获错误,
2)async/await既可以用.then又可以用try-catch捕捉

27.数组去重的方法

function unique(arr){
var newArr = [];
for(var i = 0; i < arr.length; i++){
if(newArr.indexOf(arr[i]) == -1){
newArr.push(arr[i])
}
}
return newArr;
}
var arr = [1,2,2,3,4,4,5,1,3];
var newArr = unique(arr);
console.log(newArr);

function unique(arr){
var newArr = [];
for(var i = 0; i < arr.length; i++){
for(var j = i+1; j < arr.length; j++){
if(arr[i] == arr[j]){
++i;
}
}
newArr.push(arr[i]);
}
return newArr;
}var arr = [1,2,2,3,5,3,6,5];var newArr = unique(arr);
console.log(newArr);

function unique(arr){
//Set数据结构,它类似于数组,其成员的值都是唯一的
return Array.from(new Set(arr)); // 利用Array.from将Set结构转换成数组}
var arr = [1,2,2,3,5,3,6,5];var res = unique(arr)
console.log(res );

28.JS的运行机制

js是单线程的,就是在某个事件段,js只会做一件事,只有完成某件事时,才会干下一件事
所以优秀的程序员将这些任务有分为了同步任务和异步任务。异步任务完成时,通知主线程,进而更新页面。

29.回流重绘

重绘:当页面元素样式改变不影响元素在文档流中的位置时(如background-color,border-color,visibility),浏览器只会将新样式赋予元素并进行重新绘制操作。
?改变元素的背景色
?改变文字颜色
?改变边框颜色

回流:当渲染树render tree中的一部分或全部因为元素的规模尺寸、布局、隐藏等改变时,浏览器重新渲染部分DOM或全部DOM的过程
?添加或删除可见的DOM元素
?元素的位置发生变化
?元素的尺寸发生变化(包括外边距、内边框、边框大小、高度和宽度等)
?内容发生变化,比如文本变化或图片被另一个不同尺寸的图片所替代。
?浏览器的窗口尺寸变化(因为回流是根据视口的大小来计算元素的位置和大小的)

回流必将引起重绘,而重绘不一定会引起回流。
console.log(1 + "2"+"2");122 字符串拼接
console.log(1 + +"2" +"2");32 从左往右算,1+2是3,3+“2”字符串拼接,得到“32”
console.log(1 + -"1" + "2"); 02
console.log(+ "1" + "1" + "2"); 112
console.log("A" - "B" + "2"); NAN2
console.log("A" - "B" + 2);NAN

30.解题思路

首先把字符串以?为界分割成一个数组,通过判断数组长度是否大于1来判断是否存在参数,不存在则直接返回空对象,存在则以#为界继续分割,拿到参数字符串。拿到参数字符串后,以&为界分割拿到数组,并循环,在循环每一项时,以=分割,以=前的值为键名,以=后的值为键值添加给对象 对象反出

31.箭头函数

函数的快捷写法,不需要通过function关键字创建函数,并且可以省略return关键字,但函数体内的this对象指的是定义时所在的对象,而不是使用时所在的对象;
化简规则:
Function 变成 =>;
只有1个参数可以省略小括号;
没有参数或者有多个参数不能省略小括号;
函数体内只有一行可以省略大括号,如果有返回值return,则return也要省略;
函数体内有多行,不能省略大括号;

箭头函数的this指向
“箭头函数”的this,总是指向定义时所在的对象,而不是运行时所在的对象。

bind方法不会立即执行,返回一个改变了上下文的this后的函数, 便于稍后调用; apply, call则是立即执行。

除此外, 在 ES6 的箭头函数下, call 和 apply 将失效, 对于箭头函数来说:

箭头函数体里面的 this 对象, 是定义时所在的对象,

箭头函数不能用作构造函数,也就是说不能使用 new 命令

箭头函数不可以使用 arguments 对象

32.浏览器存储

1.Cookie
2.web存储(localStorage和sessionStorage)
3.IndexedDB
缺陷
Cookie会被附加在每个HTTP请求中,所以无形中增加了流量。
由于在HTTP请求中的Cookie是明文传递的,所以安全性成问题,除非用超文本传输安全协定。
Cookie的大小限制在4KB左右,对于复杂的存储需求来说是不够用的
只能储存字符串
由于第三方Cookie的滥用,所以很多老司机在浏览网页时会禁用Cookie,所以我们不得不测试用户是否支持Cookie,这也是很麻烦的一件事
优点
首先由于操作Cookie的API很早就已经定义和实现了,因此相比于其他的数据存储方式,Cookie的兼容性非常的好,兼容现在市面上所有的主流浏览器,我们在使用它的时候完全不用担心兼容问题。

?提供了简单明了的API来进行操作
?更加安全
?可储存的数据量更大
也正是出于以上这些原因,localStorage被视为替代cookie的解决方案,但还是要注意不要在localStorage中存储敏感信息。

33.同源策略,为什么要用同源

两个页面地址中的协议,域名,端口号一致,则表示同源。

同源策略的限制:不能通过ajax请求不同域的数据,不能通过脚本操作不同域下的DOM,

为什么要用同源策略:设置同源限制主要是为了安全,如果没有同源限制存在浏览器中的cookie等其他数据可以任意读取,不同域下DOM任意操作,ajax任意请求的话如果浏览了恶意网站那么就会泄漏这些隐私数据

34.HTTP协议的流程是什么样的呢?

1.用户在浏览器(客户端)里输入或者点击一个网址链接;
2.浏览器通过网址域名查找ip地址。DNS查找方式是通过浏览器缓存(会记录DNS记录)→系统缓存→TCP/IP参数中设置的首选DNS服务器等一级一级递归解析,然后将URL中的端口号解析出来,没有的话默认80,建立TCP连接
3.浏览器会给web服务器发送一个http请求
4.服务器响应客户端报文
5.关闭连接,浏览器解析响应内容。

35.前端开发的流程

确定需求
分析与设计:业务分析 业务逻辑设计 界面设计
开发环境搭建
开发-测设 -开发-测设


https://www.xamrdz.com/backend/3yj1942668.html

相关文章: