面试题之Javascript第一篇

说说你对闭包的理解

是一个函数加上到创建函数的作用域的连接,并且关闭了函数的自由变量,一般就是一个函数A,return其内部的函数B,被return出去的B函数能够在外部访问A函数内部的变量,这时候就形成了一个B函数的变量背包,A函数执行结束后这个变量背包也不会被销毁,并且这个变量背包在A函数外部只能通过B函数访问

  1. 闭包形成的原理:作用域链,当前作用域可以访问上级作用域中的变量
  2. 闭包解决的问题: 能够让函数作用域中的变量在函数执行结束之后不会被销毁,同时也能在函数外部可以访问函数内部的局部变量
  3. 闭包带来的问题: 由于垃圾回收器不会将闭包中的变量销毁,于是就会造成内存泄露,内存泄漏积累多了就容易导致内存溢出,解决的方法是将闭包函数设置为null
  4. 闭包的优点:内部函数可以访问到外部函数的局部变量
  5. 闭包使用的场景: 回调函数 防抖节流 定时器传参
  6. 闭包的应用:能够模仿 块级作用域,能够实现柯里化,在构造函数中定义特权方法,vue中数据响应式observe中就使用了闭包

说说JS变量提升

  • 变量提升是指js的变量和函数声明会在代码编译期,提升到代码的最前面
  • 变量提升成立的前提是使用了var关键字进行了声明,并且变量提升的时候只有声明被提升,赋值并不会被提升,同时函数的声明提升会比变量的提升优先
  • 变量提升的结果:可以在变量初始化之前访问该变量,返回的是undefined,在函数声明前可以调用该函数

call、apply、bind区别

  • 共同点:改变函数体内的this指向
  • 区别:call和apply都是立即执行 ,bind不会立即执行,因为它返回的是一个函数。
    参数不同:apply参数是数组,call和bind参数一个一个挨着写

延迟加载JS的方式有哪些

  • asnyc:asnyc和html解析是同步的,不是顺序执行的
  • defer:html解析完再执行js,顺序执行

null和undefined的区别

null会被隐式的转换成0,作者觉得最好不要是对象,所以又设计了undefined,所以是先有了null再有的undefined

  • 区别:null表示“无”的对象(空对象指针),转换成数值为0
    undefined是一个表示"无"的原始值,转换成数值为NaN

JS数据类型有哪些

  • 基本类型:String number boolean undefined null symbol
  • 引用类型:Object

==和 ===有什么不同

  • ==:比较的是值 通过valueof隐式转换的
  • ===:不仅比较值还比较类型

JS微任务和宏任务

  • JS是单线程语言,JS代码执行的流程是:同步执行完==>事件循环
  • 事件循环(请求,定时器,事件)就包含了微任务和宏任务
  • 一般微任务有:promise then后面
  • 宏任务:setTimeout、setInterval注册的回调,click事件的回调
  • 要执行完宏任务的前提是清空了所有的微任务

JS作用域考题

  • 除了函数以外,没有块级作用域
  • 作用域链:内部可以访问外部变量,反之不行,注意:如果内部有优先找内部的,没有的再找外部的,
  • 优先级:声明变量>声明普通函数>参数>变量提升

JS中的类型判断

  • typeof:对于原始类型来说,除了null都可以正确显示,对于对象来说,除了函数都会显示Object,所以说typeof并不能准确判断变量到底是什么类型,所以想判断一个对象的正确类型,这个时候可以考虑用instanceof
  • instanceof:可以正确的判断对象的类型,因为内部机制是通过判断对象的原型链中是不是能找到类型的prototype
  • constructor
  • Object.prototype.toString.call()

undefined和undeclared区别

  • 已在作用域中声明但还没有赋值的变量,是undefined。相反,还没有在作用域中声明过的变量,是undeclared
  • 对于undeclared变量的引用,浏览器会报引用错误,如ReferenceError:b is not defined,但是我们可以使用typeof的安全防范机制来避免报错,因为对于undeclared或者notdefined变量,typeof会返回"undefined"

介绍js有哪些内置对象

  • js中内置对象主要指的是在程序执行前存在全局作用域的有js定义的一些全局值属性,函数和用来实例化其他对象的构造函数对象
  • 一般我们经常用到的如全局变量值NaN,undefined,全局函数如parseInt(),parseFloat()
  • 用来实列化对象的构造函数如Date,object等
  • 提供数学计算的单体内置对象如Math等

js继承的几种方式

  • 原型链继承
    缺点:在包含有引用类型的数据时,会被所有实例化对象所共享,容易造成修改的混乱,还有就是在创建子类型的时候不能向超类型传递参数
  • 借用构造函数继承
    通过在子类型的函数中调用超类型的构造函数来实现的,这一种方式解决了不能向超类型传递参数的缺点,但是存在问题是无法实现函数方法的复用,并且超类型原型定于的方法子类型也没有办法访问到
  • 组合继承(组合原型链继承和借用构造函数继承)->常用
    结合了两种模式的优点,传参和复用
    特点:1、可以继承父类原型上的属性,可以传参,可复用。
       2、每个新实例引入的构造函数属性是私有的
    缺点:调用了两次父类构造函数(耗内存),子类的构造函数会代替原型上的那个父类构造函数。
  • 原型式继承
    重点:用一个函数包装一个对象,然后返回这个函数的调用,这个函数就变成了个可以随意增添属性的实例或对象。object.create()就是这个原理
    特点:类似于复制一个对象,用函数来包装
    缺点:1、所有实例都会继承原型上的属性
       2、无法实现复用
  • 寄生式继承
    思路是创建一个用于封装继承过程的函数,通过传入一个对象,然后复制一个对象的副本,然后对对象进行扩展,最后返回这个对象,这个扩展的过程可以理解是一种继承,这种继承的优点就是对一个简单对象实现继承,如果这个对象不是我们自定义类型时,缺少是没有办法实现函数复用
  • 寄生式组合继承(常用)
    缺点是:使用超类型的实例做为子类型的原型,导致添加了不必要的原型属性,寄生式组合继承的方法是使用超类型的原型副本作为子类型的原理,这样就避免了创建不必要的属性

讲一下JS字符串截取、切割的方法

  • slice(s,e):从s位开始截取,e位结束,返回新字符串,不改变源字符串
    slice(-2,-1) 表示抽取了原数组中的倒数第二个元素到最后一个元素(不包含最后一个元素,也就是只有倒数第二个元素)。

  • substring(s,e):从s位开始截取,e结束,不包含e位在这里插入图片描述

  • substr(s,l):从s位开始截取,截取l个,不改变源字符串

  • split(s,l):把一个字符串分割成字符串数组,2个参数都是可选的,s可以是正则或者字符串,l指定返回长度,此方法常用场景是获取url链接参数,或者根据某个字符切割字符串,返回符合条件的数组,不会改变源字符串

  • join():把数组转成字符串

  • charAt(index):返回指定位置的字符

  • concat():将两个数组连接在一起;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值