JavaScript常见面试题(三)

文章目录

  • 1.对原型、原型链的理解
  • 2.原型修改、重写
  • 3.原型链指向
  • 4.对闭包的理解
  • 5. 对作用域、作用域链的理解
  • 6.对执行上下文的理解
  • 7.对this对象的理解
  • 8. call() 和 apply() 的区别?
  • 9.异步编程的实现方式?
  • 10.setTimeout、Promise、Async/Await 的区别
  • 11.对Promise的理解
  • 12.Promise的基本用法
  • Promise解决了什么问题

1.对原型、原型链的理解

原型:是一个对象,是函数的一个属性prototype(任何函数都有),通过该函数实例化出来的对象都可以继承得到原型上的所有属性和方法。
原型链:访问实例对象的属性时,首先在自己身上查找,如果自身不存在,那么就去它的原型对象(prototype属性)上查找,这个原型对象又有自己的原型,直到找到Object原型(为null),以此形成的类似链条的结构就称为原型链。

  • 对象的proto保存着该对象的构造函数的prototype

2.原型修改、重写

  • 原型的修改,修改以后对象所有的实例都可以使用新增的方法
function Person(name) {this.name = name
}
// 修改原型
Person.prototype.getName = function() {}
  • 重写,用一个新的对象来替换原来的原型。
Person.prototype = {getName: function() {}
}

注意:重写原型时,对象的构造函数可能会指向根构造函数Object

Person.prototype = {getName: function() {}
}
var p = new Person('hello')
p.constructor = Person
console.log(p.__proto__ === Person.prototype)        // true
console.log(p.__proto__ === p.constructor.prototype) // true

3.原型链指向

function Person(name) {this.name = name
}var p = new Person('John')
var p1 = new Person('Mike')console.log(p.__proto__) // Person.prototype
console.log(Person.prototype.__proto__) // Object.prototype
console.log(p.__proto__.__proto__) // Object.prototype
console.log(p.__proto__.constructor.prototype.__proto__) // Object.prototype
console.log(Person.prototype.constructor.prototype.__proto__) // Object.prototype
console.log(p1.__proto__.constructor) // Person
console.log(Person.prototype.constructor) // Person

4.对闭包的理解

概念:闭包的含义是一个函数有权访问另一个函数作用域的函数(A函数中创建B函数,函数B可以以访问到函数A中的变量,函数B就是闭包)。
用途:在函数外部能够访问到函数内部的变量;函数运行结束以后会保留对这个变量对象的引用,不会回收对象。
不足:占用更多内存,会引起内存泄漏。
应用场景:防抖节流–保存上一次运行的setTimeout(不用闭包会重新创建定时器,获取不到上一次定时器时间);函数作为返回值;vue的响应式原理;函数嵌套;

5. 对作用域、作用域链的理解

概念:作用域–>变量或者是函数能作用的范围。
作用域链:当使用一个变量时,首先在当前作用域查找,如果没找到,就去它的上层作用域去查找,直到找到或者到了全局作用域,这样形成的链式查找称为作用域链。
作用域分为函数作用域,全局作用域以及块级作用域。
全局作用域:常常定义在函数外部,全局作用域变量可以在任意位置访问。
局部作用域(函数作域):定义在函数内部,只能在函数中使用的变量,作用范围是从函数开始到结尾。
块级作用域:ES6 提供 let & const 变量实现块级作用域。
块级作用域应用场景:内部变量会覆盖外部变量(用来计数的循环变量泄漏为全局变量)。
作用:作用域链的作用是保证对执行环境有权访问的所有变量的有序访问,通过作用域链,可以访问到外层环境的变量和函数。

6.对执行上下文的理解

执行上下文分为三种:
全局执行上下文:只有一个,程序首次运行时创建,它会在浏览器中创建一个全局对象(window对象),使this指向这个全局对象。
函数执行上下文:函数被调用时创建,每次调用都会为该函数创建一个新的执行上下文。
Eval 函数执行上下文。

  • 执行上下文:在执行一点JS代码之前,需要先解析代码。解析的时候会先创建一个全局执行上下文环境,先把代码中即将执行的变量、函数声明都拿出来,变量先赋值为undefined,函数先声明好可使用。这一步执行完了,才开始正式的执行程序。
  • 执行上下文栈:JavaScript引擎使用执行上下文栈来管理执行上下文。

7.对this对象的理解

概念:this 是执行上下文中的一个属性,它指向最后一次调用这个方法的对象。
指向
函数调用:指向全局对象window
方法调用:指向这个方法的对象
构造器调用:如果一个函数用 new 调用时,函数执行前会新创建一个对象,this 指向这个新创建的对象。
apply 、 call 和 bind 调用:这三个方法都可以显示的指定调用函数的 this 指向。其中 apply 方法接收两个参数:一个是 this 绑定的对象,一个是参数数组。call 方法接收的参数,第一个是 this 绑定的对象,后面的其余参数是传入函数执行的参数。bind 方法通过传入一个对象,返回一个 this 绑定了传入对象的新函数。

8. call() 和 apply() 的区别?

都是改变函数this指向的方法

  • apply 接受两个参数,第一个参数指定了函数体内 this 对象的指向,第二个参数为一个带下标的集合,这个集合可以为数组,也可以为类数组,apply 方法把这个集合中的元素作为参数传递给被调用的函数。
  • call 传入的参数数量不固定,跟 apply 相同的是,第一个参数也是代表函数体内的 this 指向,从第二个参数开始往后,每个参数被依次传入函数。

9.异步编程的实现方式?

同步是指一个任务完成后才能执行另一个任务。
异步是把一个任务分成两段,先执行第一段,然后转而执行其他任务,等做好了准备,再回过头执行第二段。排在异步任务后面的代码,不用等待异步任务结束会马上运行。
异步编程的方法(JS 异步编程进化史:callback -> promise -> generator -> async + await)

  1. 回调函数(回调函数是一个函数,它被作为参数传递给另一个函数(通常称为“主调函数”或“高层函数”)。当主调函数完成某些操作或满足特定条件后,它会调用这个回调函数。):容易造成回调地狱问题
  2. Promise:有时会造成多个 then 的链式调用
  3. 生成器Generators/ yield
  4. async/await:async 函数是 generator 和 promise 实现的一个自动执行的语法糖,它内部自带执行器,当函数内部执行到一个 await 语句的时候,如果语句返回一个 promise 对象,那么函数将会等待 promise 对象的状态变为 resolve 后再继续向下执行。

10.setTimeout、Promise、Async/Await 的区别

  • setTimeout
console.log('script start')	//1. 打印 script start
setTimeout(function(){console.log('settimeout')	// 4. 打印 settimeout
})	// 2. 调用 setTimeout 函数,并定义其完成后执行的回调函数
console.log('script end')	//3. 打印 script start
// 输出顺序:script start->script end->settimeout
  • Promise : Promise本身是同步的立即执行函数,当在executor中执行resolve或者reject的时候, 此时是异步操作, 会先执行then/catch等,当主栈完成后,才会去调用resolve/reject中存放的方法执行
console.log('script start')
let promise1 = new Promise(function (resolve) {console.log('promise1')resolve()console.log('promise1 end')
}).then(function () {console.log('promise2')
})
setTimeout(function(){console.log('settimeout')
})
console.log('script end')
// 输出顺序: script start->promise1->promise1 end->script end->promise2->settimeout
  • async/await:await的含义为等待,也就是 async 函数需要等待await后的函数执行完成并且有了返回结果(Promise对象)之后,才能继续执行下面的代码。
async function async1(){console.log('async1 start');await async2();console.log('async1 end')
}
async function async2(){console.log('async2')
}
console.log('script start');
async1();
console.log('script end')
// 输出顺序:script start->async1 start->async2->script end->async1 end

11.对Promise的理解

Promise是异步编程的一种解决方案,它是一个对象,可以获取异步操作的消息,他的出现大大改善了异步编程的困境,避免了地狱回调。
Promise的实例有三个状态:Pending(进行中),Resolved,Rejected

  • Promise 是一个构造函数,接收一个函数作为参数,返回一个 Promise 实例。
  • 实例的状态只能由 pending 转变 resolved 或者rejected 状态,并且状态一经改变,就凝固了,无法再被改变了。
  • 在构造 Promise 的时候,构造函数内部的代码是立即执行的

12.Promise的基本用法

  • Promise构造函数接受一个函数作为参数,该函数的两个参数分别是resolve和reject。
const promise = new Promise(function(resolve, reject) {// ... some codeif (/* 异步操作成功 */){resolve(value);} else {reject(error);}
});
  • 一般情况下都会使用new Promise()来创建promise对象,但是也可以使用promise.resolve和promise.reject这两个方法
Promise.resolve(11).then(function(value){console.log(value); // 打印出11
});

方法

  1. then(),then方法可以接受两个回调函数作为参数。第一个回调函数是Promise对象的状态变为resolved时调用,第二个回调函数是Promise对象的状态变为rejected时调用。其中第二个参数可以省略。返回值根据回调函数的结果
  2. catch() 该方法相当于then方法的第二个参数,指向reject的回调函数。
  3. all() 它接收一个数组,数组的每一项都是一个promise对象。当数组中所有的promise的状态都达到resolved的时候,all方法的状态就会变成resolved,如果有一个状态变成了rejected,那么all方法的状态就会变成rejected。返回的是一个数组,保存着每一个promise对象resolve执行时的值。失败返回最先失败的值
  4. race 接受的参数是一个每项都是promise的数组,但是与all不同的是,当最先执行完的事件执行完之后,就直接返回该promise对象的值。
  5. finally 不管promise最后的状态,在执行完then或catch指定的回调函数以后,都会执行finally方法指定的回调函数。

Promise解决了什么问题

使用ajax发一个A请求后,成功后拿到数据,需要把数据传给B请求;那么需要如下编写代码:

let fs = require('fs')
fs.readFile('./a.txt','utf8',function(err,data){fs.readFile(data,'utf8',function(err,data){fs.readFile(data,'utf8',function(err,data){console.log(data)})})
})
  • List item后一个请求需要依赖于前一个请求成功后,将数据往下传递,会导致多个ajax请求嵌套的情况,代码不够直观。
  • 如果前后两个请求不需要传递参数的情况下,那么后一个请求也需要前一个请求成功后再执行下一步操作,这种情况下,那么也需要如上编写代码,导致代码不够直观。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/30520.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Eureka介绍与使用

Eureka 是 Netflix 开源的一个服务发现框架,主要用于云端中自动化地发现和注册服务。它在分布式系统中扮演着重要的角色,帮助不同的服务实例互相发现和通信。以下是关于 Eureka 的介绍及其使用方法。 ### Eureka 介绍 Eureka 是 Netflix 微服务架构中的…

高速公路收费图片分析系统深入理解

当今社会,随着交通运输业的快速发展,高速公路已成为人们出行的重要选择。而高速公路收费系统作为保障道路可持续运营的重要组成部分,其效率和准确性对于保障道路畅通和交通安全至关重要。近年来,随着技术的不断进步,高…

DSP28335:定时器

1.定时器介绍 1.1 定时器工作原理 TMS320F28335的CPU Time有三个,分别为Timer0,Timer1,Timer2,其中Timer2是为操作系统DSP/BIOS保留的,当未移植操作系统时,可用来做普通的定时器。这三个定时器的中断信号分…

读AI新生:破解人机共存密码笔记06人工智能生态系统

1. 深蓝 1.1. “深蓝”的胜利虽然令人印象深刻,但它只是延续了几十年来显而易见的趋势 1.2. 国际象棋算法的基本设计是由克劳德香农在1950年提出的 1.2.1. 这一基本设计在20世纪60年代初实现了重大改进 1.2.2. 最优秀的国际象棋程序的等级评分稳步提高&#xff…

【漏洞复现】致远OA webmail.do 任意文件下载 (CNVD-2020-62422)

免责声明: 本文内容旨在提供有关特定漏洞或安全漏洞的信息,以帮助用户更好地了解可能存在的风险。公布此类信息的目的在于促进网络安全意识和技术进步,并非出于任何恶意目的。阅读者应该明白,在利用本文提到的漏洞信息或进行相关测…

YOLOv10改进 | 注意力篇 | YOLOv10引入EMAttention(EMA)注意力

1. EMA介绍 1.1 摘要:在各种计算机视觉任务中说明了通道或空间注意机制在产生更可辨别的特征表示方面的显着有效性。 然而,通过通道降维来建模跨通道关系可能会给提取深度视觉表示带来副作用。 本文提出了一种新型高效的多尺度注意力(EMA)模块。 着眼于保留每个通道的信息…

mysql中先进先出的例子

在MySQL中,实现"先进先出"(FIFO, First In First Out)的数据结构通常不直接通过数据库的表结构来完成,因为数据库表本身并不保持元素的插入顺序。然而,你可以通过几种方法来模拟FIFO的行为。 以下是一个简单…

【idea-jdk1.8】使用Spring Initializr 创建 Spring Boot项目没有JDK8

信息差真可怕! 很久没创建springboot项目,今天使用idea的Spring Initializr 创建 Spring Boot项目时,发现java版本里,无法选择jdk1.8,只有17、21、22;前段时间也听说过,springboot将放弃java8&a…

CSS实现文字上下滚动、间歇滚动和无限滚动

目录 1、连续滚动2、间歇性向上滚动3、任意个数向上滚动 本文主要记录了如何实现文字上下滚动效果&#xff0c;实现主要就是用到了css3的两个属性&#xff1a; framekeys和 animation 1、连续滚动 <div class"scroll-continuous"><div class"content…

阿里云PAI大模型评测最佳实践

作者&#xff1a;施晨、之用、南茵、求伯、一耘、临在 背景信息 内容简介 在大模型时代&#xff0c;随着模型效果的显著提升&#xff0c;模型评测的重要性日益凸显。科学、高效的模型评测&#xff0c;不仅能帮助开发者有效地衡量和对比不同模型的性能&#xff0c;更能指导他…

vue3前端对接后端的图片验证码

vue3前端对接后端的图片验证码 <template> <image :src"captchaUrl" alt"图片验证码" click"refreshCaptcha"></image> </template><script setup>import {ref} from "vue";import {useCounterStore} …

gitlab-cicd-k8s

k8s已经准备好 kubectl get node 创建cicdYaml文件 kubectl create namespace gitlab-cicd --dry-runclient --outputyaml >> gitlab-cicd.yaml kubectl apply -f gitlab-cicd.yaml 服务器和仓库在一起可用专有地址 使用 GitLab Runner 可以自动执行 GitLab CI/CD 管道…

Vue中CSS动态样式绑定

Vue中CSS动态样式绑定与注意事项_vue css动态绑定-CSDN博客 在 Vue 中&#xff0c;你不能直接在 CSS 中直接绑定 data 中的数据&#xff0c;因为 CSS 不是响应式的。但是&#xff0c;有几种方法可以实现根据 Vue 实例中的数据来动态地改变样式&#xff1a; 内联样式绑定&…

Github 2024-06-19 开源项目日报 Top10

根据Github Trendings的统计,今日(2024-06-19统计)共有10个项目上榜。根据开发语言中项目的数量,汇总情况如下: 开发语言项目数量TypeScript项目3Rust项目2Go项目2JavaScript项目1Python项目1Dart项目1非开发语言项目1Ruby项目1HTML项目1项目化学习 创建周期:2538 天协议类…

计算机网络——网络层重要协议(IP)

网络层的作用&#xff1a;在复杂的网络环境中确定一个合适的路径 IP 协议&#xff08;Internet Protocol&#xff09; IP 数据报格式 4 位版本号&#xff1a;指定 IP 协议的版本&#xff0c;对于 IPV4 来说就是 44 位首部长度&#xff1a;用于表示 IP 首部的长度&#xff0c…

DAMA学习笔记(二)-数据治理

1.引言 数据治理&#xff08;Data Governance&#xff0c;DG&#xff09;的定义是在管理数据资产过程中行使权力和管控&#xff0c;包括计划、监控和实施。在所有组织中&#xff0c;无论是否有正式的数据治理职能&#xff0c;都需要对数据进行决策。建立了正式的数据治理规程及…

(二)Kafka 安全之使用 SSL 的加密和身份验证

目录 一. 前言 二. 使用 SSL 的加密和身份验证 2.2. 创建你自己的 CA&#xff08;Creating your own CA&#xff09; 2.3. 签署证书&#xff08;Signing the certificate&#xff09; 2.3.1. PEM 格式的 SSL 密钥和证书 一. 前言 接上一篇《&#xff08;一&#xff09;Kaf…

数据仓库之Lambda架构

Lambda架构是一种设计大规模数据处理系统的架构模式&#xff0c;它结合了批处理和实时处理的优点&#xff0c;以应对大数据的多样性、速度和规模问题。该架构主要由三个层次组成&#xff1a;批处理层&#xff08;Batch Layer&#xff09;、速度层&#xff08;Speed Layer&#…

springboot集成积木报表,怎么将平台用户信息传递到积木报表

springboot集成积木报表后怎么将平台用户信息传递到积木报表 起因是因为需要研究在积木报表做数据筛选的时候需要拿到系统当前登录用户信息做筛选新的模块 起因是因为需要研究在积木报表做数据筛选的时候需要拿到系统当前登录用户信息做筛选 官网有详细介绍怎么集成进去的&…

Eureka 学习笔记(2)加载eureka-server.properties中的配置

一 两种配置文件的方式 我们点开 EurekaServerConfig 可以看到 public interface EurekaServerConfig {/*** Gets the <em>AWS Access Id</em>. This is primarily used for* <em>Elastic IP Biding</em>. The access id should be provided with* a…