美文网首页
原生js面试题一

原生js面试题一

作者: 勋染 | 来源:发表于2023-05-08 13:47 被阅读0次

    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.http = axios; this.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.前端开发的流程

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

    相关文章

      网友评论

          本文标题:原生js面试题一

          本文链接:https://www.haomeiwen.com/subject/adllsdtx.html