js面试题(一)

简介: 笔记

扩展运算符与rest运算符的区别?


扩展运算符用三个点表示,把数组或对象展开成一系列用逗号隔开的值

rest运算符也是三个点号,不过其功能与扩展运算符恰好相反,把逗号隔开的值序列组合成一个数组

 

解决异步的方式有哪些?


promise,Async await,Generator

 

promise:基于他在进行封装比如axios,fetch等,一般用于请求数据或交互。

 

Async await:一般用于变量的赋值,比如我必须等到这个变量附上值了,在往下操作


event loop简述原理


js执行时,会进入一个执行栈,执行栈里面放的是同步任务,执行代码的时候会遇到异步代码,像promise.then方法,setTimeout这两个异步任务就会放到任务队列中,等执行栈里面的同步代码执行完毕,去执行任务队列里面的异步任务,异步任务又分为宏任务和微任务,.then方法是微任务,setTimeout是宏任务,先执行微任务,在执行宏任务,执行setTimeout的时候,又会进入执行栈,里面又是同步代码,一直这样循环

 

ajax原理


     1.创建ajax对象

     2.如果有数据的话准备数据(可选)

     2.设置请求的方法和接口地址

     3.设置请求的编码

     4.通过onreadystatechange事件去监听ajax对象请求过程

     5.发送请求

 

ajax到async的发展过程


1.原生 ajax –》开发。 可读性,可维护性差—代码冗余。

2.jQuery  ajax -》开发 可读性 可维护性差。

3.ES6 Promise 对jQuery封装的ajax改造成Prmoise封装。

4.ES8 async await 进一步进行改写--开发方便 可读性强 可维护性强。


this


代表当前上下文环境对象

1.this没有指向,指向全局对象window

 

2.new this更改为新创建的对象

 

3.函数对象.call(指定的对象,实参,实参,...)方法

   --调用函数

--改变函数内部this指向为指定的对象

 

4.函数对象.apply(指定的对象,[实参,实参,...])方法

   --调用函数

   --改变函数内部this指向为指定的对象

 

5.事件处理函数中的this,当触发事件的时候,this更改为触发事件的DOM对象

 

6.事件对象.bind(指定对象);

    --改变函数调用时的this指向

注意:bind不会调用函数


什么是同源策略?


所谓的同源,指的是协议,域名,端口相同。浏览器处于安全方面的考虑,只允许本域名下的接口交互,不同源的客户端脚本,在没有明确授权的情况下,不能读写对方的资源。

 

跨域的方式及原理?


1.jsonp   js标签script 上有一个src的属性 这个属性无视浏览器的限制 可以直接去访问外部资源

他的与缺点:

JSONP优点是简单兼容性好,可用于解决主流浏览器的跨域数据访问的问题。缺点是仅支持get方法具有局限性,不安全可能会遭受XSS攻击

 

2.cors    后台添加一个白名单直接可以进行访问外部资源

 

header("Access-Control-Allow-Qrigin: *");

 

3. postMessage

iframe代理

通过iframe标签的src,加上属性onload=要执行的函数调用,在函数中,写contentWindow.postMessage,通过这个方法来发送数据。并通过window.onmessage来接收数据

 

4.niginx反向代理   由你自己写的接口在后端调用要访问的接口地址并拿回返回值,然后返回给index.html

 

5.proxy

Webpack中devServer的proxy也可以通过changeOrigin开区跨域

 

 

Axios的特点


同时支持浏览器端和服务端的请求

支持 Promise API

拦截请求和响应

转换请求和响应数据

取消请求

自动转换JSON数据

客户端支持防止 CSRF/XSRF(跨站请求伪造)

 

es5与es6继承方式?


es5:

1. 使用对象冒充实现继承

     比如fn2类想继承fn1的属性与方法,首先在fn2中把fn1赋值给fn2的一个属性,比如名为parent,然后在fn2中调用this.parent(),这样就把fn1里的函数都在fn2中执行了,就实现了继承属性与方法,然后在通过delete this.parent,把parent删除就可以了。

2.通过call改变继承上下文

简单来说,就是通过call来改变要继承函数的this指向

3. 通过apply改变继承上下文

4. 采用原型链方式实现继承

在prototype上添加一个属性为想继承类,new的实例,这样就在原型上继承了想要继承的函数的属性和方法。

5. 采用混合模式实现继承

通过call来继承属性,prototype通过forin遍历想继承类的prototype上的方法,来继承方法。

 

es6:

通过extends来继承方法,super来继承属性。

 

处理数组用过哪些方法?


--concat( ) 连接数组

--join( ) 将数组元素按指定分隔符连接起来,返回一个字符串

--pop( ) 删除并返回数组的最后一个元素 (出栈) 常用

--push( ) 给数组添加元素 (入栈) 常用

--reverse( ) 颠倒数组中元素的顺序

--shift( ) 将元素移出数组 常用

--unshift( ) 在数组头部插入一个元素 常用

--slice( ) 返回数组的一部分 常用

--sort( ) 对数组元素进行排序  常用

--splice( ) 插入、删除或替换数组的元素 常用

--toString( ) 将数组转换成一个字符串

 

 

数组对象,变异和非变异方法?


1.数组的变异方法:push() pop() shift() unshift() splice() sort() reverse()

 

2.数组非变异方法:filter() concat() slice() forEatch(),map()

 

js判断是不是数组的方法?


方法一: 使用instanceof方法;

方法二: 使用constructor方法

                    在W3C定义中的定义:constructor 属性返回对创建此对象的构造器函数

方法三:ES5定义了Array.isArray

方法四:Array.prototype.isPrototypeOf(variable)


数组去重有哪些方法?


1.利用set的唯一性来达到去重效果(es6中最常用)

function unique(arr) {
      return Array.from(new Set(arr))
    }
    var arr = [1, 1, 'true', 'true', true, true, 15, 15, false, false, undefined, undefined, null, null, NaN, NaN, 'NaN', 0, 0, 'a', 'a', {}, {}];
    console.log(unique(arr))
//[1, "true", true, 15, false, undefined, null, NaN, "NaN", 0, "a", {}, {}]
这个无法去重空对象,后面会解决。

 

[.
(arr)]
,没看错,
arr
就是要去重的数组

 

 

2.利用双重for循环,然后splice去重(es5中最常用)

function unique(arr) {
      for (var i = 0; i < arr.length; i++) {
        // 从下标0开始和下标1逐个对比,如果有重复的,就通过splice删除
        // j所在重复的元素,因为新的元素替换上来,所以需要j--来从新判断下
        // 新替换上来的元素
        for (var j = i + 1; j < arr.length; j++) {
          if (arr[i] === arr[j]) {      
            arr.splice(j, 1);
            j--;
          }
        }
      }
      return arr;
    }
    var arr = [1, 1, 'true', 'true', true, true, 15, 15, false, false, undefined, undefined, null, null, NaN, NaN, 'NaN', 0, 0, 'a', 'a', {}, {}];
    console.log(unique(arr))
    //[1, "true", 15, false, undefined, NaN, NaN, "NaN", "a", {…}, {…}]     //NaN和{}没有去重,两个null直接消失了

 

3. 利用indexOf去重

function unique(arr) {
      // 先创建一个空数组
      var array = [];
      for (var i = 0; i < arr.length; i++) {
        // 如果indexOf返回-1,就证明没有重复的元素,就push到新数组中
        if (array.indexOf(arr[i]) === -1) {
          array.push(arr[i])
        }
      }
      // 循环完毕后,返回这个新数组
      return array;
    }
    var arr = [1, 1, 'true', 'true', true, true, 15, 15, false, false, undefined, undefined, null, null, NaN, NaN, 'NaN', 0, 0, 'a', 'a', {}, {}];
    console.log(unique(arr))
   // [1, "true", true, 15, false, undefined, null, NaN, NaN, "NaN", 0, "a", {…}, {…}]  //NaN、{}没有去重


4.利用sort()排序方法来实现

function unique(arr) {
      // 先通过sort进行排序,把相同的元素先放到一起
      arr = arr.sort()
      // 然后把原数组的第一个元素存到arrry里
      var arrry = [arr[0]];
      for (var i = 1; i < arr.length; i++) {
        // 如果当前的和上一个不相等,就添加进数组,如果重复就直接跳过
        if (arr[i] !== arr[i - 1]) {
          arrry.push(arr[i]);
        }
      }
      return arrry;
    }
    var arr = [1,  'true',1, 'true', true, true, 15, 15, false, false, undefined, undefined, null, null, NaN, NaN, 'NaN', 0, 0, 'a', 'a', {}, {}];
    console.log(unique(arr))
// [0, 1, 15, "NaN", NaN, NaN, {…}, {…}, "a", false, null, true, "true", undefined]      //NaN、{}没有去重

5.利用es7中新增的includes方法

function unique(arr) {
      var array = [];
      for (var i = 0; i < arr.length; i++) {
        //includes 检测数组是否有某个值,如果包含则返回 true,否则返回false
        if (!array.includes(arr[i])) {
          array.push(arr[i]);
        }
      }
      return array
    }
    var arr = [1, 1, 'true', 'true', true, true, 15, 15, false, false, undefined, undefined, null, null, NaN, NaN, 'NaN', 0, 0, 'a', 'a', {}, {}];
    console.log(unique(arr))
    //[1, "true", true, 15, false, undefined, null, NaN, "NaN", 0, "a", {…}, {…}]     //{}没有去重

 

6.利用hasOwnProperty()方法和filter

// 对象方法hasOwnProperty()方法返回一个布尔值,判断对象是否包含特定的自身(非继承)属性。
    function unique(arr) {
      // 创建一个空对象
      var obj = {};
      // 通过filter过滤
      return arr.filter(function (item, index, arr) {
        // 如果里面的元素相等,那么就返回false把他过滤掉,如果返回true,就留下
        return obj.hasOwnProperty(typeof item + item) ? false : (obj[typeof item + item] = true)
      })
    }
    var arr = [1, 1, 'true', 'true', true, true, 15, 15, false, false, undefined, undefined, null, null, NaN, NaN, 'NaN', 0, 0, 'a', 'a', {}, {}];
    console.log(unique(arr))
//[1, "true", true, 15, false, undefined, null, NaN, "NaN", 0, "a", {…}]   //所有的都去重了

 

处理字符串用过哪些方法?


       --charAt( ) 返回字符串中的第n个字符 –例1  例2

       --charCodeAt( ) 返回字符串中的第n个字符的Unicode编码

       --concat( ) 连接字符串

       --fromCharCode( ) 从字符编码创建—个字符串

       --indexOf( ) 检索字符串  常用

       --lastIndexOf( ) 从后向前检索一个字符串

       --localeCompare( ) 用本地特定的顺序来比较两个字符串 是否相等

       --match( ) 找到一个或多个正则表达式的匹配

       --replace( ) 替换一个与正则表达式匹配的字符串

       --search( ) 检索与正则表达式相匹配的字符串

       --slice( ) 截取取一个字符串串

       --split( ) 将字符串分割成字符串数组

       --substr( ) 截取字符串 常用

       --substring( ) 返回字符串的一个子串  常用

       --toLowerCase( ) 将字符串转换成小写

       --toUpperCase( ) 将字符串转换成大写

       --valueOf( ) 返回对象的原始值

       --toString( ) 返回字符串

目录
相关文章
|
2月前
|
JSON JavaScript 前端开发
Javascript基础 86个面试题汇总 (附答案)
该文章汇总了JavaScript的基础面试题及其答案,涵盖了JavaScript的核心概念、特性以及常见的面试问题。
46 3
|
2月前
|
前端开发 JavaScript
JavaScript 面试系列:如何理解 ES6 中 Generator ?常用使用场景有哪些?
JavaScript 面试系列:如何理解 ES6 中 Generator ?常用使用场景有哪些?
|
3月前
|
JavaScript 前端开发
常见的JS面试题
【8月更文挑战第5天】 常见的JS面试题
59 3
|
3天前
|
JSON JavaScript 前端开发
[JS]面试官:你的简历上写着熟悉jsonp,那你说说它的底层逻辑是怎样的?
本文介绍了JSONP的工作原理及其在解决跨域请求中的应用。首先解释了同源策略的概念,然后通过多个示例详细阐述了JSONP如何通过动态解释服务端返回的JavaScript脚本来实现跨域数据交互。文章还探讨了使用jQuery的`$.ajax`方法封装JSONP请求的方式,并提供了具体的代码示例。最后,通过一个更复杂的示例展示了如何处理JSON格式的响应数据。
13 2
[JS]面试官:你的简历上写着熟悉jsonp,那你说说它的底层逻辑是怎样的?
|
21天前
|
Web App开发 JavaScript 前端开发
前端Node.js面试题
前端Node.js面试题
|
3月前
|
存储 JavaScript 前端开发
2022年前端js面试题
2022年前端js面试题
37 0
|
3月前
|
JavaScript 前端开发 程序员
JS小白请看!一招让你的面试成功率大大提高——规范代码
JS小白请看!一招让你的面试成功率大大提高——规范代码
|
3月前
|
JavaScript 前端开发 UED
小白请看! 大厂面试题 :如何用JS实现瀑布流
小白请看! 大厂面试题 :如何用JS实现瀑布流
|
3月前
|
存储 JavaScript 前端开发
JS浅拷贝及面试时手写源码
JS浅拷贝及面试时手写源码
|
3月前
|
JavaScript 前端开发
JS:类型转换(四)从底层逻辑让你搞懂经典面试问题 [ ] == ![ ] ?
JS:类型转换(四)从底层逻辑让你搞懂经典面试问题 [ ] == ![ ] ?