【面试题】常见前端基础面试题(HTML,CSS,JS) |
您所在的位置:网站首页 › js的变量提升面试题 › 【面试题】常见前端基础面试题(HTML,CSS,JS) |
box-sizeing: content-box表示标准盒模型(默认值) box-sizeing: border-box表示IE盒模型(怪异盒模型) 怎么让一个 div 水平垂直居中通过 verticle-align:middle 实现垂直居中 通过父元素设置伪元素 :before ,然后设置子元素 verticle-align:middle 实现垂直居中 通过绝对定位实现垂直居中 通过 transform 实现垂直居中 使用弹性盒子居中 BFC所谓 BFC,指的是一个独立的布局环境,BFC 内部的元素布局与外部互不影响。 触发 BFC 的方式有很多,常见的有:设置浮动 overflow 设置为 auto、scroll、hidden positon 设置为 absolute、fixed 常见BFC的应用解决浮动元素令父元素高度坍塌的问题 解决非浮动元素被浮动元素覆盖问题 解决外边距垂直方向重合问题 JS 的基本数据类型有哪些?基本数据类型和引用数据类型的区别 基本数据类型JavaScript共有八种数据类型,分别是 Undefined、Null、Boolean、Number、String、Object、Symbol、BigInt 这些数据可以分为原始数据类型和引用数据类型: 栈:原始数据类型(Undefined、Null、Boolean、Number、String) 堆:引用数据类型(对象、数组和函数) 基本数据类型和引用数据类型的区别访问方式: 原始值:访问到的是值 引用值:访问到的是引用地址 (js不允许直接访问保存在堆中的对象、首先得到在堆中的地址,然后按照这个地址去获得对象的值) 比较方式: 原始值:比较的是值 引用值: 比较的是引用的地址 变量赋值: 原始值赋值:赋值的是新值,与原来互不影响 引用值赋值:赋值的是地址,指向原值所在堆内存中的地址 动态属性: 原始值:赋值的是值 引用值:赋值的是地址 ES6 新增哪些东西箭头函数 字符串模板 支持模块化(import、export) 类(class、constructor、extends) let、const 关键字 新增一些数组、字符串等内置构造函数方法,例如 Array.from、Array.of 、Math.sign、Math.trunc 等 新增一些语法,例如扩展操作符、解构、函数默认参数等 新增一种基本数据类型 Symbol 新增元编程相关,例如 proxy、Reflect Set 和 Map 数据结构 Promise Generator 生成器 let const var 的区别?什么是块级作用域?如何用?var 定义的变量,是函数作用域,没有块的概念,可以跨块访问, 不能跨函数访问,有变量提升。 let 定义的变量,只能在块作用域里访问,不能跨块访问,也不能跨函数访问,无变量提升,不可以重复声明。 const 用来定义常量,使用时必须初始化(即必须赋值),只能在块作用域里访问,而且不能修改,无变量提升,不可以重复声明。 var不存在暂时性死区,let和const存在暂时性死区 let和const创建的全局变量没有给window设置相应的属性 暂时性死区:使用 let / const 命令声明变量之前,该变量都是不可用的 箭头函数与普通函数的区别箭头函数没有自己的this、会捕获其所在的上下文的this值,作为自己的this值 箭头函数继承来的this指向永远不会改变 call()、apply()、bind()等方法不能改变箭头函数中this的指向 箭头函数是匿名函数,不能作为构造函数,不能使用new 箭头函数没有自己的arguments 箭头函数没有prototype(原型) 箭头函数不能用作Generator函数,不能使用yeild关键字 bind,apply,call三者的区别三者都可以改变函数的this对象指向 三者第一个参数都是this要指向的对象,如果如果没有这个参数或参数为undefined或null,则默认指向全局window 三者都可以传参,但是apply是数组,而call是参数列表,且apply和call是一次性传入参数,而bind可以分为多次传入 bind是返回绑定this之后的函数,apply、call 则是立即执行 是否了解 JavaScript 中的包装类型?包装对象 : 就是当基本类型以对象的方式去使用时,JavaScript 会转换成对应的包装类型,相当于 new 一个对象,内容和基本类型的内容一样,然后当操作完成再去访问的时候,这个临时对象会被销毁,然后再访问时候就是 undefined 代码理解: var str = 'hello'; str.number = 10; //假设我们想给字符串添加一个属性 number ,后台会有如下步骤 ( var _str = newString('hello'); // 1 找到对应的包装对象类型,然后通过包装对象创建出一个和基本类型值相同的对象 _str.number = 10; // 2 通过这个对象调用包装对象下的方法 但结果并没有被任何东西保存 _str =null; // 3 这个对象又被销毁 ) console.log(str.number); // undefined 当执行到这一句的时候,因为基本类型本来没有属性,后台又会重新重复上面的步骤 ( var str = newString('hello');// 1 找到基本包装对象,然后又新开辟一个内存,创建一个值为 hello 对象 str.number = undefined;// 2 因为包装对象下面没有 number 这个属性,所以又会重新添加,因为没有值,所以值是未定义;然后弹出结果 str =null; // 3 这个对象又被销毁 ) 复制代码 JS 中如何进行数据类型的转换?类型转换可以分为两种,隐性转换和显性转换 显性转换主要分为三大类:数值类型、字符串类型、布尔类型 三大类的原始类型值的转换规则我就不一一列举了,更多详情文章链接 👉 juejin.cn/post/695617… 数值类型(引用类型转换) Number({a: 1}) // NaNNumber([1, 2, 3]) // NaNNumber([5]) // 5 第一步,调用对象自身的`valueOf`方法。如果返回原始类型的值,则直接对该值使用`Number`函数,不再进行后续步骤。 第二步,如果`valueOf`方法返回的还是对象,则改为调用对象自身的`toString`方法。如果`toString`方法返回原始类型的值, 则对该值使用`Number`函数,不再进行后续步骤。 第三步,如果`toString`方法返回的是对象,就报错。 补充一点:`valueOf`和`toString`方法,都是可以自定义的 复制代码 字符串类型(引用类型转换) String({a: 1}) // "[object Object]"String([1, 2, 3]) // "1,2,3"`String`方法背后的转换规则,与`Number`方法基本相同,只是互换了`valueOf`方法和`toString`方法的执行顺序。 复制代码 隐性转换 类型转换前转换后number44string“1”1string“”0booleantrue1booleanfalse0undefinedundefinedNaNnullnull0详情看上方👆文章链接 闭包闭包是指有权访问另一个函数作用域中的变量的函数 ———— 《JavaScript高级程序设计》 闭包用途:能够访问函数定义时所在的词法作用域(阻止其被回收) 私有变量化 模拟块级作用域 创建模块 闭包缺点:闭包调用函数的变量,并且这个变量在函数执行完之后,不能释放,会导致函数的变量一直保存在内存中,过多的闭包可能会导致内存泄漏。 解决:变量设置成null 原型和原型链 原型每个对象都有一个 proto 属性,该属性指向自己的原型对象 每个构造函数都有一个 prototype 属性,该属性指向实例对象的原型对象 原型对象里的 constructor 指向构造函数本身 原型链当试图访问一个对象的属性时,它不仅仅在该对象上搜寻,还会搜寻该对象的原型,以及该对象的原型的原型,依次层层向上搜索,直到找到一个名字匹配的属性或到达原型链的末尾null (1)全局作用域 最外层函数和最外层函数外面定义的变量拥有全局作用域 所有未定义直接赋值的变量自动声明为全局作用域 所有window对象的属性拥有全局作用域 全局作用域有很大的弊端,过多的全局作用域变量会污染全局命名空间,容易引起命名冲突。 (2)函数作用域 函数作用域声明在函数内部的变零,一般只有固定的代码片段可以访问到 作用域是分层的,内层作用域可以访问外层作用域,反之不行 (3)块级作用域 使用ES6中新增的let和const指令可以声明块级作用域,块级作用域可以在函数中创建也可以在一个代码块中的创建(由{ }包裹的代码片段) let和const声明的变量不会有变量提升,也不可以重复声明 在循环中比较适合绑定块级作用域,这样就可以把声明的计数器变量限制在循环内部。 作用域链在当前作用域中查找所需变量,但是该作用域没有这个变量,那这个变量就是自由变量。 如果在自己作用域找不到该变量就去父级作用域查找,依次向上级作用域查找,直到访问到window对象就被终止,这一层层的关系就是作用域链。 作用域链有一个非常重要的特性,那就是作用域中的值是在函数创建的时候,就已经被存储了,是静态的。 防抖和节流我们在平时开发的时候,会有很多场景会频繁触发事件,比如说搜索框实时发请求,onmousemove、resize、onscroll 等,有些时候,我们并不能或者不想频繁触发事件,这时候就应该用到函数防抖和函数节流。 函数防抖(debounce),指的是短时间内多次触发同一事件,只执行最后一次,或者只执行最开始的一次,中间的不执行。 函数节流(throttle),指连续触发事件但是在 n 秒中只执行一次函数。即 2n 秒内执行 2 次… 。节流如字面意思,会稀释函数的执行频率。 区别在于:防抖动是将多次执行变为最后一次执行,节流是将多次执行变成每隔一段时间执行 宏任务和微任务常见的宏任务有:setTimeout、setInterval、requestAnimationFrame、script等。 常见的微任务有:new Promise( ).then(回调)、MutationObserver 等。 宏任务和微任务的执行流程,总结起来就是:js在调用时,优先取出微任务,并且在执行过程中如果创建了新的作业,则放在本次执行完后紧接着调用,微任务执行完成后,再取出宏任务执行 哪些情况会导致内存泄漏以下四种情况会造成内存的泄漏: 意外的全局变量: 由于使用未声明的变量,而意外的创建了一个全局变量,而使这个变量一直留在内存中无法被回收。 被遗忘的计时器或回调函数: 设置了 setInterval 定时器,而忘记取消它,如果循环函数有对外部变量的引用的话,那么这个变量会被一直留在内存中,而无法被回收。 脱离 DOM 的引用: 获取一个 DOM 元素的引用,而后面这个元素被删除,由于一直保留了对这个元素的引用,所以它也无法被回收。 闭包: 不合理的使用闭包,从而导致某些变量一直被留在内存当中。 请介绍一下 JavaScript 中的垃圾回收站机制JavaScript 具有自动垃圾回收机制。垃圾收集器会按照固定的时间间隔周期性的执行。 JavaScript 常见的垃圾回收方式:标记清除、引用计数方式。 标记清除方式:工作原理:当变量进入环境时,将这个变量标记为“进入环境”。当变量离开环境时,则将其标记为“离开环境”。标记“离开环境”的就回收内存。 工作流程: 垃圾回收器,在运行的时候会给存储在内存中的所有变量都加上标记; 去掉环境中的变量以及被环境中的变量引用的变量的标记; 被加上标记的会被视为准备删除的变量; 垃圾回收器完成内存清理工作,销毁那些带标记的值并回收他们所占用的内存空间。 引用计数方式:工作原理:跟踪记录每个值被引用的次数。 工作流程: 声明了一个变量并将一个引用类型的值赋值给这个变量,这个引用类型值的引用次数就是 1; 同一个值又被赋值给另一个变量,这个引用类型值的引用次数加 1; 当包含这个引用类型值的变量又被赋值成另一个值了,那么这个引用类型值的引用次数减 1; 当引用次数变成 0 时,说明没办法访问这个值了; 当垃圾收集器下一次运行时,它就会释放引用次数是 0 的值所占的内存。 防抖,节流是什么 最后作原理:当变量进入环境时,将这个变量标记为“进入环境”。当变量离开环境时,则将其标记为“离开环境”。标记“离开环境”的就回收内存。 工作流程: 垃圾回收器,在运行的时候会给存储在内存中的所有变量都加上标记; 去掉环境中的变量以及被环境中的变量引用的变量的标记; 被加上标记的会被视为准备删除的变量; 垃圾回收器完成内存清理工作,销毁那些带标记的值并回收他们所占用的内存空间。 引用计数方式:工作原理:跟踪记录每个值被引用的次数。 工作流程: 声明了一个变量并将一个引用类型的值赋值给这个变量,这个引用类型值的引用次数就是 1; 同一个值又被赋值给另一个变量,这个引用类型值的引用次数加 1; 当包含这个引用类型值的变量又被赋值成另一个值了,那么这个引用类型值的引用次数减 1; 当引用次数变成 0 时,说明没办法访问这个值了; 当垃圾收集器下一次运行时,它就会释放引用次数是 0 的值所占的内存。 防抖,节流是什么 最后 |
今日新闻 |
推荐新闻 |
CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3 |