js高级面试题

前端面试题

1、typeof检测数据

instanceof 检测数据引用类型的区别

1、值类型
    1)基本类型数据是值类型
    2)保存与复制的是值本身
    3)使用typeof检测数据的类型 
    String(字符串) number(数字) Boolean(布尔值)  undefined(未定义或未赋值) null(空)**
    复杂类型: Object (对象) Array(数组) Function(函数)
2、引用类型    [1,2] instanceof Array // true   返回布尔值
    1)保存与复制的是指向对象的一个指针
    2)使用  instanceof 检测数据类型
    3)使用 new() 方法构造出的对象是引用型

2、什么是深拷贝什么是浅拷贝

答: 浅拷贝: 拷贝对象的一层属性,如果对象里面还有对象,拷贝的是地址, 两者之间修改会有影响,适用于对象里面属性的值是简单数据类型的.
  深拷贝: 拷贝对象的多层属性,如果对象里面还有对象,会继续拷贝,使用递归去实现.

3、如何实现深拷贝和浅拷贝

答:
浅拷贝:
    var obj = {
      class: 'UI',
      age: 20,
      love: 'eat'
    }
    function getObj(obj) {
      var newObj = {}
      for (var k in obj) {
        newObj[k] = obj[k]
      }
      return newObj
    }
    var obj2 = getObj(obj)
    console.log(obj2)
​
深拷贝: 
        var obj = {
      class: '前端',
      age: 26,
      love: {
      friuts : 'apple',
      meat: 'beef'
      }
    }
        function getObj(obj) {
      var newObj = {}
      for (var k in obj) {
        /* if (typeof obj[k] == 'object') {
          newObj[k] = getObj(obj[k])
        } else {
          newObj[k] = obj[k]
        } */
        newObj[k] = typeof obj[k] == 'object' ? getObj(obj[k]) : obj[k]
      }
      return newObj
    }
    var obj2 = getObj(obj)
    console.log(obj2)

4、对闭包的理解?并能举出闭包的例子

答: 闭包 函数和声明该函数的词法环境的组合(两个嵌套关系的函数,内部函数可以访问外部函数定义的变量)
    闭包的优点:1、形成私有空间,避免全局变量的污染
               2、持久化内存,保存数据
    闭包的缺点:1、持久化内存,导致内存泄露
    解决:1、尽快避免函数的嵌套,以及变量的引用
          2、执行完的变量,可以赋值null,让垃圾回收机制,进行回收释放内存(当不在引用的变量,垃圾回收机制就会回收)
例: 点击li获取当前下标
    <ul>
      <li>111</li>
      <li>222</li>
      <li>333</li>
      <li>444</li>
      <li>555</li>
    </ul>
      var lis = document.querySelectorAll('li')
      for (var i = 0; i < lis.length; i++) {
        (function (j) {
          lis[j].onclick = function () {
            console.log(j)
          }
        })(i)
      }

5、什么是原型和原型链

答: 原型: 函数都有prototype属性,这个属性的值是个对象,称之为原型
   原型链: 对象都有__proto__属性,这个属性指向它的原型对象,原型对象也是对象,也有__proto__属性,指向原型对象的原型对象,这样一层一层形成的链式结构称为原型链.

6、call、apply和bind的区别

答: 1. call和apply方法都可以调用函数,方法内的第一个参数可以修改this的指向
    2. call方法可以有多个参数,除了第一个参数,其他参数作为实参传递给函数
             apply方法最多有2个参数,第二个参数是个数组或伪数组,数组里面的每一项作为实参传递给函数
    3. bind方法不能调用函数,它会创建一个副本函数,并且绑定新函数的this指向bind返回的新的函数

7、es6-es10新增常用方法

答: 
es6:
1、let、const
2、解构赋值   let { a, b } = { a: 1, b: 2 }
3、箭头函数   ()=>{}
4、模板字符串  ``
5、扩展运算符  ...arr
6、数组方法:map、filter、some 等等
7、类:class关键字
8、promise 主要用于异步计算
9、函数参数默认值 fn(a = 1) {}
10、对象属性简写 let a = 1; let obj = {a}
11、模块化:import--引入、exprot default--导出
​
es7:
1、 includes()方法,用来判断一个数组是否包含一个指定的值,根据情况,如果包含则返回true,否则返回false。
​
es8:
1、async/await
​
es9:
1、Promise.finally() 允许你指定最终的逻辑   
​
es10:
1、数组Array的flat()和 flatmap()
   flat:方法最基本的作用就是数组降维
      var arr1 = [1, 2, [3, 4]];
            arr1.flat(); 
            // [1, 2, 3, 4]
​
        var arr3 = [1, 2, [3, 4, [5, 6]]];
        arr3.flat(2);
        // [1, 2, 3, 4, 5, 6]
​
        //使用 Infinity 作为深度,展开任意深度的嵌套数组
        arr3.flat(Infinity); 
        // [1, 2, 3, 4, 5, 6]
   flatmap:方法首先使用映射函数映射(遍历)每个元素,然后将结果压缩成一个新数组

8、let、const和var的区别

1、var声明变量存在提升(提升当前作用域最顶端),let和const是不存在变量提升的情况
2、var没有块级作用,let和const存在块级作用域
3、var允许重复声明,let和const在同一作用域不允许重复声明
4、var和let声明变量可以修改,const是常量不能改变

9、怎么理解函数的防抖和节流

答:
1、定义:
防抖: 就是指触发事件后在n秒内函数只能执行一次,如果在n秒内又触发了事件,则会重新计算函数执行时间。
     例如:设定1000毫秒执行,当你触发事件了,他会1000毫秒后执行,但是在还剩500毫秒的时候你又触发了事件,那就会重新开始1000毫秒之后再执行
​
节流: 就是指连续触发事件但是在设定的一段时间内中只执行一次函数。
     例如:设定1000毫秒执行,那你在1000毫秒触发在多次,也只在1000毫秒后执行一次
     
2、防抖和节流的实现:
    <body>
    <input type="text" class="ipt" />
    <script>
      var timerId = null
      document.querySelector('.ipt').onkeyup = function () {
        // 防抖
        if (timerId !== null) {
          clearTimeout(timerId)
        }
        timerId = setTimeout(() => {
          console.log('我是防抖')
        }, 1000)
      }
​
      document.querySelector('.ipt').onkeyup = function () {
        // 节流
        console.log(2)
        if (timerId !== null) {
          return
        }
​
        timerId = setTimeout(() => {
          console.log('我是节流')
          timerId = null
        }, 1000)
      }
​
    </script>
  </body>

10、js的运行机制是什么

答:js是单线程执行的,页面加载时,会自上而下执行主线程上的同步任务,当主线程代码执行完毕时,才开始执行在任务队列中的异步任务。具体如下  
    1.所有同步任务都在主线程上执行,形成一个执行栈。
    2.主线程之外,还存在一个"任务队列(eventloop队列或者消息队列)"。只要异步任务有了运行结果,就在"任务队列"之中放置一个事件。
    3.一旦"执行栈"中的所有同步任务执行完毕,系统就会读取"任务队列",看看里面有哪些事件。哪些对应的异步任务,于是结束等待状态,进入执行栈,开始执行。
    4.主线程不断重复上面的第三步。

11、怎么理解面向对象

答:1、面向对象是一种软件开发的思想和面向过程是相对应的,就是把程序看作一个对象,将属性和方法封装其中,以提高代码的灵活性、复用性、可扩展性。
  2、面向对象有三大特性:封装、继承、多态。
       封装:把相关的信息(无论数据或方法)存储在对象中的能力
       继承:由另一个类(或多个类)得来类的属性和方法的能力
       多态:编写能以多种方法运行的函数或方法的能力
   3、基本思想是使用对象,类,继承,封装等基本概念来进行程序设计
     易维护
     易扩展
     开发工作的重用性、继承性高,降低重复工作量。
     缩短了开发周期

12、数组如何进行降维(扁平化)

1、利用Array.some方法判断数组中是否还存在数组,es6展开运算符连接数组
       let arr = [1,2,[3,4]]
        while (arr.some(item => Array.isArray(item))) {
            arr = [].concat(...arr);
        }
2、使用数组的concat方法
    let arr = [1,2,[3,4]]
     let result = []
     result = Array.prototype.concat.apply([], arr)
​
3、 使用数组的concat方法和扩展运算符
    var arr = [1,2,[3,4]]
    var result = []
    result = [].concat(...arr)
        
4、es6中的flat函数也可以实现数组的扁平化
    let arr = [1,2,['a','b',['中','文',[1,2,3,[11,21,31]]]],3];
    let result = arr.flat( Infinity )
    注意:flat方法的infinity属性,可以实现多层数组的降维

14、斐波那契数列

// 斐波那契数列
  function fiB(n) {
    if (n == 1 || n == 2) {
        return 1
      }
        return fn(n - 1) + fn(n - 2)
   }
    console.log(fiB(10))

<think>好的,我现在需要处理用户关于JavaScript高级编程面试题的请求。首先,用户明确提到想查找相关的高级面试题,可能是为了准备面试或深入学习。根据提供的引用内容,特别是引用[2]、[3]和[4],里面提到了闭包、作用域、浅拷贝、JSONP等知识点,这些都是JS面试中的常见考点。 首先,我需要整理这些引用中的内容,看看有哪些可以提取的知识点。比如引用[3]详细讨论了闭包和作用域链,引用[2]提到了JSONP的实现,引用[4]涉及浅拷贝。这些都是核心概念,应该在回答中重点覆盖。 接下来,用户可能需要一个结构清晰的回答,涵盖高频考点、示例代码和相关问题。根据用户提供的示例结构,应该分模块讲解每个知识点,并附上代码示例,如闭包的应用、JSONP的实现等。 还要注意用户提到的系统级指令,比如数学公式的格式要求,但在这个问题中可能不太涉及数学内容,所以主要关注代码和文本结构。确保所有行内代码用$...$,但用户示例中的代码块用的是Python,这里需要切换成JavaScript,并使用正确的语法。 另外,用户要求生成相关问题,这需要根据每个知识点设计相关问题,比如闭包的应用场景、深拷贝与浅拷贝的区别等。需要确保问题有针对性,能帮助用户进一步巩固知识。 最后,引用标识要自然地添加在引用内容的末尾,比如在讲解闭包时引用[3],JSONP部分引用[2],浅拷贝部分引用[4]。同时要确保回答结构符合用户的要求,分点清晰,帮助用户逐步理解和掌握高级JavaScript面试题。</think>### JavaScript高级编程面试题汇总 --- #### 一、高频考点解析 1. **闭包与作用域链** - **闭包**:函数嵌套时,内层函数可访问外层作用域变量,即使外层函数已执行完毕。常用于封装私有变量或实现模块化[^3]。 ```javascript function createCounter() { let count = 0; return { increment: () => count++, getCount: () => count }; } const counter = createCounter(); counter.increment(); console.log(counter.getCount()); // 输出1 ``` - **作用域链**:内层作用域可访问外层变量,但外层无法访问内层变量。例如以下代码会报错: ```javascript function outer() { function inner() { var a = 10; } console.log(a); // ReferenceError: a未定义 } ``` 2. **JSONP原理与实现** - **原理**:利用`<script>`标签跨域加载资源,并通过回调函数处理返回数据[^2]。 ```javascript function handleResponse(data) { console.log('Received:', data); } const script = document.createElement('script'); script.src = 'https://api.example.com/data?callback=handleResponse'; document.body.appendChild(script); ``` 3. **深拷贝与浅拷贝** - **浅拷贝**:仅复制对象第一层属性,引用类型仍指向同一地址[^4]。 ```javascript const obj = { a: 1, b: { c: 2 } }; const shallowCopy = { ...obj }; shallowCopy.b.c = 3; console.log(obj.b.c); // 输出3(原对象被修改) ``` - **深拷贝**:完全复制对象及其嵌套结构,常用`JSON.parse(JSON.stringify(obj))`或递归实现。 --- #### 二、异步编程与事件循环 1. **Promise与async/await** - **Promise链式调用**: ```javascript fetch('https://api.example.com/data') .then(response => response.json()) .then(data => console.log(data)) .catch(error => console.error(error)); ``` - **async/await**: ```javascript async function fetchData() { try { const response = await fetch('https://api.example.com/data'); const data = await response.json(); console.log(data); } catch (error) { console.error(error); } } ``` 2. **事件循环机制** - 执行顺序:同步代码 > 微任务(Promise.then) > 宏任务(setTimeout)。 --- #### 三、设计模式与性能优化 1. **观察者模式** ```javascript class EventEmitter { constructor() { this.events = {}; } on(event, listener) { (this.events[event] || (this.events[event] = [])).push(listener); } emit(event, ...args) { (this.events[event] || []).forEach(listener => listener(...args)); } } ``` 2. **内存泄漏防范** - 及时移除事件监听。 - 避免意外的全局变量。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值