• 前端面试题集锦(4)


    目录

    1、对 this 的理解, 三种改变 this 的方式 ?

    2、cookie, localStorage,sessionStorage 的区别 ?

    3、原生 ajax 的流程 ?  

    4、如何实现继承 ?

    5、函数的节流和防抖是什么 ?

    6、什么是 Promise 以及promise的作用 ?

    7、Promsie 和 async/await 的区别和使用 ?

    8、对于数组去重你有哪些办法 ?

    9、如何实现数组的复制 ?

    10、git 的常用指令有哪些 ?


    1、对 this 的理解, 三种改变 this 的方式 ?

    1. 任何情况下直接在 script 中写入的 this 都是 window
    2. 函数中的 this 非严格模式: this 指向 window , 严格模式时: this 指向 undefined
    3. 箭头函数的 this
           ✏️  this都指向箭头函数外上下文环境的 this 指向
    4. 对象中 this
    ✏️  对象属性的this 指向对象外上下文环境的 this
    ✏️  对象方法( 普通函数 ) 中的 this ,指向当前对象 ( 谁执行该方法, this 就指向谁 )
    5. 回调函数的 this 指向
    ✏️  setTimeout setInterval 回调函数不管是否是严格模式都会指向 window
    ✏️  通过在函数内执行当前回调函数 非严格模式:this 指向 window , 严格模式时: this 指向undefined
    ✏️  递归函数中的this 非严格模式: this 指向 window , 严格模式时: this 指向 undefined
    ✏️   使用 arguments 0 执行函数时 this 指向 arguments
    ✏️  事件中的回调函数,this 指向事件侦听的对象 (e.currentTarget);
    6 call apply bind 方法执行时 this 的指向
    ✏️  如果call,apply,bind 传参时,第一个参数传入的不是 null 或者 undefined ,传入什么 this 指向什么
    ✏️  如果第一个参数传入的是null 或者 undefined , 非严格模式下指向 window
    7 、在 ES6 的类中 this 的指向
    ✏️  构造函数中的this 指向实例当前类所产生的新的实例对象
    ✏️  类中实例化方法中this 指向谁执行该方法, this 指向谁
    ✏️  类中静态方法中this 执行该类或者该类的构造函数
    ✏️  类中实例化箭头方法,this 仍然指向当前类实例化的实例对象
    8 ES5 的原型对象中 this 的指向
    ✏️  在原型的方法中,this 指向实例化当前构造函数的实例化对象(谁执行该方法, this 指向谁) ;
    ✏️  三种改变this 指向的方式
    ✏️  函数名.call (this,....) this 写谁就指谁。
    ✏️  函数名.apply(this,[ 参数 1 ,参数 2 ...]) this 写谁就指谁。
    ✏️  函数名. bind (this,1,2,3) this 写谁就指谁。

    2cookie, localStorage,sessionStorage 的区别 ?

    📕 cookie

    存储方式
    存储用户信息,获取数据需要与服务器建立连接。
    以路径存储,上层路径不能访问下层的路径 cookie ,下层的路径 cookie 可以访问上层的路径 cookie
    作用与特性
    可存储的数据有限,且依赖于服务器,无需请求服务器的数据尽量不要存放在 cookie 中,以免影响页面性能。
    可设置过期时间。
    存储数量及大小 将 cookie 控制在 4095B 以内,超出的数据会被忽略。
    IE6 或更低版本 最多存 20 cookie
    IE7 及以上
    版本 多可以有 50 个;
    Firefox 50 个;
    chrome Safari 没有做硬性限制。
    cookie 最大特征就是可以在页面与服务器间互相传递,当发送或者接受数据时自动传递

    📕 localStorage

    存储客户端信息,无需请求服务器。
    数据永久保存,除非用户手动清理客户端缓存。
    开发者可自行封装一个方法,设置失效时间。 5M 左右,各浏览器的存储空间有差异。
    任何地方都可以存都可以取
    操作简单

    📕 sessionStorage

    存储客户端信息,无需请求服务器。
    数据保存在当前会话,刷新页面数据不会被清除,结束会话(关闭浏览器、关闭页面、跳转页面)数据失效。
    5M 左右,各浏览器的存储空间有差异。
    同页面不同窗口中数据不会共享

    3、原生 ajax 的流程 ?  

    1. <script>
    2. //创建xhr
    3. var xhr=new XMLHTTPRequest()
    4. //侦听通信状态改变的事件
    5. xhr.addEventListener("readystatechange",readyStateChangeHandler);
    6. //Method 分为 get post put delete等等
    7. //Async 异步同步
    8. //name和password是用户名和密码
    9. xhr.open(Method,URL,Async,name,password)
    10. //发送内容给服务器
    11. xhr.send(内容)
    12. function readyStateChangeHandler(e){
    13. //当状态是4时,并且响应头成功200时,
    14. if(xhr.readyState===4 && xhr.status===200){
    15. //打印返回的消息
    16. console.log(xhr.response)
    17. }
    18. }
    19. script>

    4、如何实现继承 ?

    📕  对于 JavaScript 来说,继承有两个要点:
                1. 复用父构造函数中的代码
                2. 复用父原型中的代码第一种实现复用父构造函数中的代码,我们可以考虑调用父构造函数并将 this 绑定到子构造函数。
    📕  第一种方法:复用父原型中的代码,我们只需改变原型链即可。将子构造函数的原型对象的 proto 属性指向父构造函数的原型对象。
    📕  第二种实现
    使用 new 操作符来替代直接使用 proto 属性来改变原型链。
    📕  第三种实现
    使用一个空构造函数来作为中介函数,这样就不会将构造函数中的属性混到 prototype
    1. <script>
    2. function A(x,y){
    3. this.x = x
    4. this.y = y
    5. }
    6. A.prototype.run = function(){}
    7. // 寄生继承 二者一起使用
    8. function B(x,y){
    9. A.call(this,x,y) // 借用继承
    10. }
    11. B.prototype = new A() // 原型继承
    12. // 组合继承
    13. Function.prototype.extends = function(superClass){
    14. function F(){}
    15. F.prototype = superClass.prototype
    16. if(superClass.prototype.constructor !== superClass){
    17. Object.defineProperty(superClass.prototype,'constructor',{value:superClass})
    18. }
    19. let proto = this.prototype
    20. this.prototype = new F()
    21. let names = Reflect.ownKeys(proto)
    22. for(let i = 0; i < names.length;i++){
    23. let desc = Object.getOwnPropertyDescriptor(proto,names[i])
    24. Object.defineProperty(this.prototypr,name[i],desc)
    25. }
    26. this.prototype.super = function(arg){
    27. superClass.apply(this,arg)
    28. }
    29. this.prototype.supers = superClass.prototype
    30. }
    31. script>
    📕  第四种实现
        es6 类的继承 extends

    5、函数的节流和防抖是什么 ?

    📕 节流

    节流是指当一个事件触发的时候 , 为防止事件的连续频繁触发 , 设置定时器 , 达到一种一段事件内只触发一次的效果 , 在当前事件内不会再次触发, 当前事件结束以后 , 再次触发才有效 .
    1. <script>
    2. function thro(cb,wait){
    3. let timeOut
    4. return function(){
    5. if(timeOut) return
    6. timeOut = setTimeout(function(){
    7. cb()
    8. clearTimeout(timeOut)
    9. timeOut = null
    10. },wait)
    11. }
    12. }
    13. script>

    📕 防抖

    防抖是指当一个事件触发的时候 , 为防止频繁触发事件 , 设置定时器 , 以达到一种 频繁触发期间不处理 , 只有当最后一次连续触发结束以后才处理

    1. <script>
    2. function debounce(cb,wait){
    3. let timer
    4. return function(){
    5. clearTimeout(timer)
    6. timer = setTimeout(()=>cb(),wait)
    7. }
    8. }
    9. script>

    6、什么是 Promise 以及promise的作用 ?

    Promise 是异步编程的一种解决方案:从语法上讲, promise 是一个对象,从它可以获取异步操作的消息;
    从本意上讲,它是承诺,承诺它过一段时间会给你一个结果。
    promise 有三种状态: pending( 等待态 ) fulfiled( 成功态 ) rejected( 失败态 ) ;状态一旦改变,就不会再变。创造promise 实例后,它会立即执行
    promise 是用来解决两个问题的:
    回调地狱,代码难以维护, 常常第一个的函数的输出是第二个函数的输入这种现象
    promise 可以支持多个并发的请求,获取并发请求中的数据
    这个 promise 可以解决异步的问题,本身不能说 promise 是异步的

    7Promsie async/await 的区别和使用 ?

    ✏️  函数前面多了一个async 关键字。 await 关键字只能用在 async 定义的函数内。 async 函数会隐式地返回一个promise ,该 promise reosolve 值就是函数 return 的值。
    ✏️  第1 点暗示我们不能在 外层代码中使用 await ,因为不在 async 函数内。使用:
              1.async await 是配对使用的, await 存在于 async 的内部。否则会报错 。
              2.await 表示在这里等待一个 promise 返回,再接下来执行。
              3.await 后面跟着的应该是一个 promise 对象,(也可以不是,如果不是接下来也没什么意义了

    8、对于数组去重你有哪些办法 ?

    📕  第一种:
    1. for(var i=0;ilength;i++){
    2. for(var j=i+1;jlength;){
    3. if(arr[i]===arr[j]) arr.splice(j,1);
    4. else j++; // 核心
    5. }
    6. }

    📕 第二种:

    1. var arr1=[];
    2. for(var i=0;ilength;i++){
    3. for(var j=0;jlength;j++){
    4. if(arr1[j]===arr[i]) continue xt;
    5. }
    6. arr1.push(arr[i]);
    7. }

    📕 第三种:

    1. var arr1=[];
    2. for(var i=0;ilength;i++){
    3. if(arr1.indexOf(arr[i])<0) arr1.push(arr[i])
    4. }

    📕 第四种:

    1. var arr1=[];
    2. for(var i=0;ilength;i++){
    3. if(!(~arr1.indexOf(arr[i]))) arr1.push(arr[i])
    4. }

    📕 第五种:

    1. var arr1=[];
    2. for(var i=0;ilength;i++){
    3. if(!arr1.includes(arr[i])) arr1.push(arr[i])
    4. }

    📕 第六种:

    1. arr=[1,2,3,1,2,3,1,2,3]
    2. new Set(arr);

    9、如何实现数组的复制 ?

    📕  for循环逐一复制
    1. var arr1=[];
    2. for(var i=0;ilength;i++){
    3. if(i in arr) arr1[i]=arr[i]
    4. }

    📕 ...方式

    var arr1=[...arr];

    📕 slice方法

    var arr1=arr.slice();

    📕 concat方法

    var arr1=arr.concat();

    📕 map方法

    var arr1=arr.map(item=>item);

    📕 reduce方法

    var arr1=arr.reduce((v,t)=>v.push(t),[])

    10、git 的常用指令有哪些 ?

    git branch 分支查看
    git branch branch_1 增加分支
    git checkout branch 分支切换
    git merge branch_1 合并分支 ( 合并前要切换当前分支至 master)
    git branch -d branch_1 删除分支
    git remote 查看当前仓库管理的远程仓库信息
    git remote show origin 查看指定的远程仓库的详细信息
    git push --set-upstream origin branch_1 第一次将本地分支推到远程仓库
    git push < 远程主机名 > < 本地分支名 >:< 远程分支名 > 将本地分支推到远程分支
    git pull < 远程主机名 > < 远程分支 >:< 本地分支 > 将远程分支拉到本地分支
    git branch -d branch_0 删除本地合并后分支
    git brench -D branch_0 删除本地未合并分支
    it push origin --delete branch_0 删除远程分支
    git restore [filename] 进行清除工作区的改变
    git tag 查看标签
    git tag v1.0.0 打标签
    git push origin v1.0.0 tag 同步到远程服务器
  • 相关阅读:
    JS标准库
    git--基础--04--分支管理规范
    2、kubeadm安装单master集群
    【Logback+Spring-Aop】实现全面生态化的全链路日志追踪系统服务插件「Logback-MDC篇」
    SparkSQL系列-6、外部数据源 DataSource?
    AOF持久化
    数据结构之队列
    VMwareworkstation安装Centos7教程
    力扣刷题流程--记录用
    让生活更加精致的APP?
  • 原文地址:https://blog.csdn.net/weixin_48649246/article/details/128153095