html+css+js面试题,作为一个刚转正的前端小趴菜的独白,真的很重要!!!

js常见面试题:常见的三剑客html+css+js
从各个网站搜罗集合的面试题,文章仅供学习使用,不作为商业用途,如有侵权请联系我。
各位小趴菜们,一起冲吧!!!!

Html5篇:

注:h5常问的就是语义化标签,以及相比较之前新增加的内容,即h5的新特性。

1.html存储:(必记!!!)

可以看看这些:

https://juejin.cn/post/6923331849708109838

https://juejin.cn/post/6844903945253421069

localStorage、sessionStorage、cookie、session几种web数据存储方式对比总结:
(1)cookie 和 session

cookie 和 session 都是普遍用来跟踪浏览用户身份的会话方式。

(2)cookie 和 session 区别
  • cookie 数据存放在客户端,session 数据放在服务器端
  • cookie 本身并不安全,考虑到安全应当使用 session。
  • session 会在一定时间内保存在服务器上。如果访问量比较大,会比较消耗服务器的性能。考虑到减轻服务器性能方面的开销,应当使用 cookie 。
  • 单个 cookie 保存的数据不能超过 4K(会问的),很多浏览器都限制一个域名最多保存 50 个 cookie。 将登陆信息等重要信息存放为 session、其他信息如果需要保留,可以放在 cookie 中。

session 主要是服务端使用处理数据

(3)cookie 的使用

cookie 可通过 document.cookie 获取全部 cookie。它是一段字符串,是键值对的形式。操作起来有些麻烦,可引入封装好的库进行使用,比如 js-cookie点我。API 也很简洁:

Cookies.set("name", "value", { expires: 7 }); // 设置一个cookie,7天后失效

Cookies.get("name"); // => 'value'

Cookies.remove("name");
localStorage 和 sessionStorage

在 web 本地存储场景上,cookie 的使用受到种种限制,最关键的就是存储容量太小和数据无法持久化存储。

在 HTML 5 的标准下,出现了 localStorage 和 sessionStorage 供我们使用。

  • cookie、localStorage 以及 sessionStorage 的异同点:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YTqZgA91-1664284524187)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\1664198992657.png)]

  • 应用场景:localStorage 适合持久化缓存数据,比如页面的默认偏好配置等;sessionStorage 适合一次性临时数据保存。

  • WebStorage( localStorage 和 sessionStorage ) 本身就提供了比较好用的方法:

    localStorage.setItem("name", "value");
    localStorage.getItem("name"); // => 'value'
    localStorage.removeItem("name");
    localStorage.clear(); // 删除所有数据
    
    sessionStorage.setItem("name", "value");
    sessionStorage.setItem("name");
    sessionStorage.setItem("name");
    sessionStorage.clear();
    

    注意事项:

    • localStorage 写入的时候,如果超出容量会报错,但之前保存的数据不会丢失。
    • localStorage 存储容量快要满的时候,getItem 方法性能会急剧下降。
    • web storage 在保存复杂数据类型时,较为依赖 JSON.stringify,在移动端性能问题比较明显。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bz2nlHLG-1664284524192)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\1664198458171.png)]

2.html性能优化:

(1) 压缩 HTML:将注释、空格和空行从生产文件中删除。

(2) 免脚本阻塞加载。确保在使用 JavaScript 代码之前加载 CSS .

(3) 尽可能使用 async 和 defer

(4) DNS 预取:一次 DNS 查询时间大概在 60-120ms 之间或者更长 , 提前解析网页中可能的网络连接域名

(5) 减少内联脚本的数量

(6) 缩小和压缩图像

(7) 最小化文件数量

(8) 页面缓存:在不设置页面缓存的情况下,每次刷新页面会重新读取服务器文件。设置页面缓存,每次刷新可从本地读取,提高页面加载效率

3.对HTML语义化的理解:

语义化是指根据内容的结构化(内容语义化),选择合适的标签(代码语义化)。通俗来讲就是用正确的标签做正确的事情。

语义化的优点如下:

  • 对机器友好,带有语义的文字表现力丰富,更适合搜索引擎的爬虫爬取有效信息,有利于SEO。除此之外,语义类还支持读屏软件,根据文章可以自动生成目录;
  • 对开发者友好,使用语义类标签增强了可读性,结构更加清晰,开发者能清晰的看出网页的结构,便于团队的开发与维护。

常见的语义化标签:

<header></header>  头部

<nav></nav>  导航栏

<section></section>  区块(有语义化的div)

<main></main>  主要区域

<article></article>  主要内容

<aside></aside>  侧边栏

<footer></footer>  底部
4.DOCTYPE 有什么用?

‘ <!DOCTYPE> ’声明位于 HTML 文档中的第一行,处于 ‘’标签之前。告知浏览器的解析器使用标准模式渲染文档。DOCTYPE 不存在或格式不正确会导致文档以兼容模式呈现。

5.页面导入样式时,使用 link 和 @import 有什么区别?

link 属于 XHTML 标签,除了加载 CSS 外,还能用于定义 RSS,定义 rel 连接属性等作用;而 @import 是 CSS 提供的,只能用于加载 CSS;

页面被加载的时,link 会同时被加载,而 @import 引用的 CSS 会等到页面被加载完再加载;

@import 是CSS2.1 提出的,只在 IE5 以上才能被识别,而 link 是 XHTML 标签,无兼容问题;

link 方式的样式的权重高于 @import 的权重。

6.为什么最好把 JS 的 script 标签放在 body 之前,有例外情况吗?

脚本在下载和执行期间会阻止 HTML 解析。把

例外情况:当你的脚本里包含 document.write()时。 但是现在,document.write() 不推荐使用。

同时,将

7.iframe 是什么?有什么优缺点?(记一两个就好,可能问的不会特别多)

HTML内联框架元素 表示嵌入的浏览上下文。它能够将另一个 HTML 页面嵌入到当前页面中。

iframe 是用来在网页中插入第三方页面,早期的页面使用 iframe 主要是用于导航栏这种很多页面都相同的部分,这样在切换页面的时候避免重复下载。

tips:可以将提示文字放在 之间,来提示某些不支持 iframe 的浏览器

优点

  • 便于修改,模拟分离,像一些信息管理系统会用到。
  • iframe 能够原封不动的把嵌入的网页展现出来。
  • 如果有多个网页引用 iframe,那么你只需要修改 iframe 的内容,就可以实现调用的每一个页面内容的更改,方便快捷。
  • 网页如果为了统一风格,头部和版本都是一样的,就可以写成一个页面,用 iframe 来嵌套,可以增加代码的可重用。
  • 并行加载脚本
  • security sandbox(安全沙盒)
  • 解决加载缓慢的第三方内容。如:图标和广告等的加载问题。

缺点

  • 没有语意。搜索引擎无法解读这种页面,不利于SEO
  • 会产生很多页面,不容易管理。
  • 即使内容为空,加载也需要时间。
  • iframe 的创建比一般的 DOM 元素慢了 1-2 个数量级
  • 很多的移动设备(PDA手机)无法完全显示框架,设备兼容性差。
  • iframe 框架页面会增加服务器的 http 请求,对于大型网站是不可取的。
  • iframe 会阻塞主页面的 onload 事件。
  • iframe 和主页面共享连接池,而浏览器对相同域的连接有限制,所以会影响页面的并行加载。
  • 如果需要使用 iframe,最好通过 javascript 动态给 iframe 添加 src 属性值,这样可以绕开以上两个问题
  • iframe 框架结构有时会让人感到迷惑,如果框架个数多的话,可能会出现上下、左右滚动条,会分散访问者的注意力,用户体验度差。

tips:除非特殊需要,一般不推荐使用。目前 iframe 的优点完全可以使用 Ajax 实现,因此已经没有必要使用 iframe 了。

CSS3篇:

1.CSS选择器及其优先级:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yNnF2ix3-1664284524194)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\1664199659640.png)]

对于选择器的优先级

  • 标签选择器、伪元素选择器:1
  • 类选择器、伪类选择器、属性选择器:10
  • id 选择器:100
  • 内联样式:1000

注意事项:

  • !important声明的样式的优先级最高;
  • 如果优先级相同,则最后出现的样式生效;
  • 继承得到的样式的优先级最低;
  • 通用选择器(*)、子选择器(>)和相邻同胞选择器(+)并不在这四个等级中,所以它们的权值都为 0 ;
  • 样式表的来源不同时,优先级顺序为:内联样式 > 内部样式 > 外部样式 > 浏览器用户自定义样式 > 浏览器默认样式。
2.居中(一定要会哦!:)

看这个:https://juejin.cn/post/7119133627568357384

3.控制元素的显示与隐藏(一次性说出这几个基本就够了)
  • visibility:控制元素显示隐藏
  • z-index(设置position:relative)
  • opacity: 0;
  • display:none;
  • .clip { position: absolute; clip: rect(0 0 0 0); } .out { position: relative; left: -999em; }

明白这几个的区别:

visibility可以实现 元素不可见,不能点击,辅助设备无法访问,但占据空间保留 。

**z-index:-1并设置relative,**可以通过设置不同层级,让元素不可见,不能点击,但占据空间,键盘可访问。

opacity: 0; 通过设置透明度,实现元素隐藏。

display:none 直接不展示, 是 Web 显隐交互中出场频率最高的一种隐藏方式

clip/clip-path :使用元素裁剪的方法来实现元素的隐藏,这种方法下,元素仍在页面中占据位置,但是不会响应绑定的监听事件。

display:none与visibility:hidden的区别

这两个属性都是让元素隐藏,不可见。两者区别如下:

(1)在渲染树中

  • display:none会让元素完全从渲染树中消失,渲染时不会占据任何空间;
  • visibility:hidden不会让元素从渲染树中消失,渲染的元素还会占据相应的空间,只是内容不可见。

(2)是否是继承属性

  • display:none是非继承属性,子孙节点会随着父节点从渲染树消失,通过修改子孙节点的属性也无法显示;
  • visibility:hidden是继承属性,子孙节点消失是由于继承了hidden,通过设置visibility:visible可以让子孙节点显示; (3)修改常规文档流中元素的 display 通常会造成文档的重排,但是修改visibility属性只会造成本元素的重绘;

(4)如果使用读屏器,设置为display:none的内容不会被读取,设置为visibility:hidden的内容会被读取。

还有更多的可以看看这篇:

https://juejin.cn/post/7111575766730539038

4.对盒模型的理解(IE退出历史舞台了,可以不管IE盒子模型)

img

盒模型都是由四个部分组成的,分别是margin、border、padding和content。

标准盒模型和IE盒模型的区别在于设置width和height时,所对应的范围不同:

  • 标准盒模型的width和height属性的范围只包含了content
5.CSS3中有哪些新特性:

新增各种CSS选择器 (: not(.input):所有 class 不是“input”的节点)

圆角 (border-radius:8px)

多列布局 (multi-column layout)

阴影和反射 (Shadoweflect)

文字特效 (text-shadow)

文字渲染 (Text-decoration)

线性渐变 (gradient)

旋转 (transform)

增加了旋转,缩放,定位,倾斜,动画,多背景

6.CSS 优化和提高性能的方法有哪些?(每个记两条就够了)

加载性能:

(1)css压缩:将写好的css进行打包压缩,可以减小文件体积。

(2)css单一样式:当需要下边距和左边距的时候,很多时候会选择使用 margin:top 0 bottom 0;但margin-bottom:bottom;margin-left:left;执行效率会更高。

(3)减少使用@import,建议使用link,因为后者在页面加载时一起加载,前者是等待页面加载完成之后再进行加载。

选择器性能:

(1)关键选择器(key selector)。选择器的最后面的部分为关键选择器(即用来匹配目标元素的部分)。CSS选择符是从右到左进行匹配的。当使用后代选择器的时候,浏览器会遍历所有子元素来确定是否是指定的元素等等;

(2)如果规则拥有ID选择器作为其关键选择器,则不要为规则增加标签。过滤掉无关的规则(这样样式系统就不会浪费时间去匹配它们了)。

(3)避免使用通配规则,如*{}计算次数惊人,只对需要用到的元素进行选择。

(4)尽量少的去对标签进行选择,而是用class。

(5)尽量少的去使用后代选择器,降低选择器的权重值。后代选择器的开销是最高的,尽量将选择器的深度降到最低,最高不要超过三层,更多的使用类来关联每一个标签元素。

(6)了解哪些属性是可以通过继承而来的,然后避免对这些属性重复指定规则。

渲染性能:

(1)慎重使用高性能属性:浮动、定位。

(2)尽量减少页面重排、重绘。

(3)去除空规则:{}。空规则的产生原因一般来说是为了预留样式。去除这些空规则无疑能减少css文档体积。

(4)属性值为0时,不加单位。

(5)属性值为浮动小数0.**,可以省略小数点之前的0。

(6)标准化各种浏览器前缀:带浏览器前缀的在前。标准属性在后。

(7)不使用@import前缀,它会影响css的加载速度。

(8)选择器优化嵌套,尽量避免层级过深。

(9)css雪碧图,同一页面相近部分的小图标,方便使用,减少页面的请求次数,但是同时图片本身会变大,使用时,优劣考虑清楚,再使用。

(10)正确使用display的属性,由于display的作用,某些样式组合会无效,徒增样式体积的同时也影响解析性能。

(11)不滥用web字体。对于中文网站来说WebFonts可能很陌生,国外却很流行。web fonts通常体积庞大,而且一些浏览器在下载web fonts时会阻塞页面渲染损伤性能。

可维护性、健壮性:

(1)将具有相同属性的样式抽离出来,整合并通过class在页面中进行使用,提高css的可维护性。

(2)样式与内容分离:将css代码定义到外部css中。

7.单行、多行文本溢出隐藏
  • 单行文本溢出
overflow: hidden;            // 溢出隐藏
text-overflow: ellipsis;      // 溢出用省略号显示
white-space: nowrap;         // 规定段落中的文本不进行换行
复制代码
  • 多行文本溢出
overflow: hidden;            // 溢出隐藏
text-overflow: ellipsis;     // 溢出用省略号显示
display:-webkit-box;         // 作为弹性伸缩盒子模型显示。
-webkit-box-orient:vertical; // 设置伸缩盒子的子元素排列方式:从上到下垂直排列
-webkit-line-clamp:3;        // 显示的行数
8.Sass、Less 是什么?为什么要使用他们?

他们都是 CSS 预处理器,是 CSS 上的一种抽象层。他们是一种特殊的语法/语言编译成 CSS。 例如 Less 是一种动态样式语言,将 CSS 赋予了动态语言的特性,如变量,继承,运算, 函数,LESS 既可以在客户端上运行 (支持 IE 6+, Webkit, Firefox),也可以在服务端运行 (借助 Node.js)

9.页面布局
常见的CSS布局单位: 常用的布局单位包括像素(px),百分比(%),emremvw/vh

可以看看这个

https://juejin.cn/post/6993091221262434311

px、em、rem的区别及使用场景

三者的区别:

  • px是固定的像素,一旦设置了就无法因为适应页面大小而改变。
  • em和rem相对于px更具有灵活性,他们是相对长度单位,其长度不是固定的,更适用于响应式布局。
  • em是相对于其父元素来设置字体大小,这样就会存在一个问题,进行任何元素设置,都有可能需要知道他父元素的大小。而rem是相对于根元素,这样就意味着,只需要在根元素确定一个参考值。

使用场景:

  • 对于只需要适配少部分移动设备,且分辨率对页面影响不大的,使用px即可 。
  • 对于需要适配各种移动设备,使用rem,例如需要适配iPhone和iPad等分辨率差别比较挺大的设备。
10.如何根据设计稿进行移动端适配?

移动端适配主要有两个维度:

  • 适配不同像素密度, 针对不同的像素密度,使用 CSS 媒体查询,选择不同精度的图片,以保证图片不会失真;
  • 适配不同屏幕大小, 由于不同的屏幕有着不同的逻辑像素大小,所以如果直接使用 px 作为开发单位,会使得开发的页面在某一款手机上可以准确显示,但是在另一款手机上就会失真。为了适配不同屏幕的大小,应按照比例来还原设计稿的内容。

为了能让页面的尺寸自适应,可以使用 rem,em,vw,vh 等相对单位。

11.定位与浮动:
为什么需要清除浮动?清除浮动的方式
12.position的属性有哪些,区别是什么

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-BNgfJLp5-1664284524204)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\1664201440455.png)]

更多的可以看这个:https://blog.csdn.net/lgno2/article/details/109446721?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522166427899216782428640717%2522%252C%2522scm%2522%253A%252220140713.130102334…%2522%257D&request_id=166427899216782428640717&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2alltop_positive~default-1-109446721-null-null.142v50control,201v3control_1&utm_term=css%E9%9D%A2%E8%AF%95%E9%A2%98&spm=1018.2226.3001.4187

JS篇:

掌握这篇过js的面试题就基本没问题了:

https://juejin.cn/post/6940945178899251230

https://juejin.cn/post/6941194115392634888

总览一下:img

es6的知识点,面试常问(可以看看阮一峰的)https://es6.ruanyifeng.com/#docs/destructuring

工作了很久感觉帮助最大的一篇文章(常用的es6)https://juejin.cn/post/7016520448204603423

把经常经常问的,超高频问题列一下:

1.var、let、const的区别:(小可爱可以把这个背下来,经常会用的,面试不出意外也会问)

一.var的特点

1.存在变量提

console.log(a); // undefined 
var a = 10; //
编译过程 var a;
console.log(a); // undefined 
a = 10;

2.一个变量可多次声明,后面的声明会覆盖前面的声明

var a = 10; 
var a = 20;
console.log(a); // 20

3.在函数中使用 var声明变量的时候,该变量是局部的

var a = 10;
function change(){ 
    var a = 20;
} 
change(); 
console.log(a); // 10

而如果在函数内不使用var,该变量是全局的

var a = 10; 
function change(){
    a = 20
}; 
change(); 
console.log(a); // 20

二.let的特点

  1. 不存在变量提升,let声明变量前,该变量不能使用(暂时性死区)

    console.log(a); // ReferenceError: a is not defined let
    a = 10;
    
  2. let命令所在的代码块内有效,在块级作用域内有效

{ 
    let a = 10;
}
console.log(a); // ReferenceError: a is not defined
  1. let不允许在相同作用域中重复声明,注意是相同作用域,不同作用域有重复声明不会报错

    let a = 10;
    let a = 20; // Uncaught SyntaxError: Identifier 'a' has already been declared 
    let a = 10;
    { 
        let a = 20;
    } // ok
    

三.const

  1. const声明一个只读的变量,声明后,值就不能改变

    const a = 10;
    a = 20; // TypeError: Assignment to constant variable.
    
  2. const必须初始化

    const a; // SyntaxError: Missing initializer in const declaration 
    const a = 10; // ok
    
  3. const并不是变量的值不能改动,而是变量指向的内存地址所保存的数据不得改动

    const obj = { 
        age: 17 
    }
    obj.age = 18; // ok
    obj = { 
        age: 18
    } // SyntaxError: Identifier 'obj' has already been declared
    
  4. let该有的特点const都有

变量提升: var声明的变量存在变量提升,即变量可以在声明之前调用,值为undefined
let和const不存在变量提升,即它们所声明的变量一定要在声明后使用,否则报错

块级作用域 :var不存在块级作用域,let和const存在块级作用域 。

重复声明 : var允许重复声明变量,let和const在同一作用域不允许重复声明变量

修改声明的变量 : var和let可以,const声明一个只读的常量。一旦声明,常量的值就不能改变,但对于对象和数据这种引用类型,内存地址不能修改,可以修改里面的值。

2.常用的js方法(这些是经常用的,要记住的):
数组的能改变自身的7个方法:
  1. push 尾部增加
  2. pop 尾部删除
  3. shift 头部删除
  4. unshift 头部增加
  5. splice 删除某一个或者替换
  6. sort 排序
  7. revese 反转

这里用过vue的小伙伴应该非常熟悉,这是vue中经常提到的几个方法

es3 方法
  • arr.indexOf 查找一个元素是否在数组中
  • concat(…items) 合并返回一个新数组
  • slice 截取部分返回一个新数组
  • join 拼接返回一个字符串
es5 方法
  • filter 过滤符合条件的项,组成一个新数组
  • some 检查有一项为true,即为true
  • every 检查每一项为true 才为true
  • reduce
es6方法
  • find 找出符合条件的第一项
  • findIndex 找出符合条件的第一项index
  • includes 数组中是否包含
  • flat 拉平多维数组
  • […arr] 数组的扩展运算符 将数组浅copy一份
  • Array.from 转数组
数组的迭代方法
  • forEach
  • map 返回一个新数组
  • keys values entries

综合写下来,数组的常用方法的确也不算少了,有时候对于某个方法记忆模糊了,需要再查一下。但是我们需要清楚的知道某个方法能处理什么情况,知道在什么时候使用才是真正掌握了。

像是map/forEach/filter/includes/keys这几个几乎是天天用的,其他的可能一两天就用一下,但是用的频率也很高。

3. null和undefined区别

首先 Undefined 和 Null 都是基本数据类型,这两个基本数据类型分别都只有一个值,就是 undefined 和 null。

undefined 代表的含义是未定义,null 代表的含义是空对象。一般变量声明了但还没有定义的时候会返回 undefined,null主要用于赋值给一些可能会返回对象的变量,作为初始化。

undefined 在 JavaScript 中不是一个保留字,这意味着可以使用 undefined 来作为一个变量名,但是这样的做法是非常危险的,它会影响对 undefined 值的判断。我们可以通过一些方法获得安全的 undefined 值,比如说 void 0。

当对这两种类型使用 typeof 进行判断时,Null 类型化会返回 “object”,这是一个历史遗留的问题。当使用双等号对两种类型的值进行比较时会返回 true,使用三个等号时会返回 false。

4.为什么0.1+0.2 ! == 0.3,如何让其相等

在开发过程中遇到类似这样的问题:

let n1 = 0.1, n2 = 0.2
console.log(n1 + n2)  // 0.30000000000000004

这里得到的不是想要的结果,要想等于0.3,就要把它进行转化:

(n1 + n2).toFixed(2) // 注意,toFixed为四舍五入

toFixed(num) 方法可把 Number 四舍五入为指定小数位数的数字。那为什么会出现这样的结果呢?

计算机是通过二进制的方式存储数据的,所以计算机计算0.1+0.2的时候,实际上是计算的两个数的二进制的和。0.1的二进制是0.0001100110011001100...(1100循环),0.2的二进制是:0.00110011001100...(1100循环),这两个数的二进制都是无限循环的数。那JavaScript是如何处理无限循环的二进制小数呢?

一般我们认为数字包括整数和小数,但是在 JavaScript 中只有一种数字类型:Number,它的实现遵循IEEE 754标准,使用64位固定长度来表示,也就是标准的double双精度浮点数。在二进制科学表示法中,双精度浮点数的小数部分最多只能保留52位,再加上前面的1,其实就是保留53位有效数字,剩余的需要舍去,遵从“0舍1入”的原则。

根据这个原则,0.1和0.2的二进制数相加,再转化为十进制数就是:0.30000000000000004

5.箭头函数与普通函数的区别(面试能够说出三四个区别就好啦)

(1)箭头函数比普通函数更加简洁

  • 如果没有参数,就直接写一个空括号即可
  • 如果只有一个参数,可以省去参数的括号
  • 如果有多个参数,用逗号分割
  • 如果函数体的返回值只有一句,可以省略大括号
  • 如果函数体不需要返回值,且只有一句话,可以给这个语句前面加一个void关键字。最常见的就是调用一个函数:
let fn = () => void doesNotReturn();

(2)箭头函数没有自己的this

箭头函数不会创建自己的this, 所以它没有自己的this,它只会在自己作用域的上一层继承this。所以箭头函数中this的指向在它在定义时已经确定了,之后不会改变。

(3)箭头函数继承来的this指向永远不会改变

var id = 'GLOBAL';
var obj = {
  id: 'OBJ',
  a: function(){
    console.log(this.id);
  },
  b: () => {
    console.log(this.id);
  }
};
obj.a();    // 'OBJ'
obj.b();    // 'GLOBAL'
new obj.a()  // undefined
new obj.b()  // Uncaught TypeError: obj.b is not a constructor

对象obj的方法b是使用箭头函数定义的,这个函数中的this就永远指向它定义时所处的全局执行环境中的this,即便这个函数是作为对象obj的方法调用,this依旧指向Window对象。需要注意,定义对象的大括号{}是无法形成一个单独的执行环境的,它依旧是处于全局执行环境中。

(4)call()、apply()、bind()等方法不能改变箭头函数中this的指向

var id = 'Global';
let fun1 = () => {
    console.log(this.id)
};
fun1();                     // 'Global'
fun1.call({id: 'Obj'});     // 'Global'
fun1.apply({id: 'Obj'});    // 'Global'
fun1.bind({id: 'Obj'})();   // 'Global'

(5)箭头函数不能作为构造函数使用

构造函数在new的步骤在上面已经说过了,实际上第二步就是将函数中的this指向该对象。 但是由于箭头函数时没有自己的this的,且this指向外层的执行环境,且不能改变指向,所以不能当做构造函数使用。

(6)箭头函数没有自己的arguments

箭头函数没有自己的arguments对象。在箭头函数中访问arguments实际上获得的是它外层函数的arguments值。

(7)箭头函数没有prototype

(8)箭头函数不能用作Generator函数,不能使用yeild关键字

6.箭头函数的this指向哪⾥?

箭头函数不同于传统JavaScript中的函数,箭头函数并没有属于⾃⼰的this,它所谓的this是捕获其所在上下⽂的 this 值,作为⾃⼰的 this 值,并且由于没有属于⾃⼰的this,所以是不会被new调⽤的,这个所谓的this也不会被改变。
可以⽤Babel理解⼀下箭头函数:

// ES6 
const obj = { 
  getArrow() { 
    return () => { 
      console.log(this === obj); 
    }; 
  } 
}

转化后:

// ES5,由 Babel 转译
var obj = { 
   getArrow: function getArrow() { 
     var _this = this; 
     return function () { 
        console.log(_this === obj); 
     }; 
   } 
};
7.JavaScript有哪些内置对象

标准内置对象的分类:

(1)值属性,这些全局属性返回一个简单值,这些值没有自己的属性和方法。例如 Infinity、NaN、undefined、null 字面量

(2)函数属性,全局函数可以直接调用,不需要在调用时指定所属对象,执行结束后会将结果直接返回给调用者。例如 eval()、parseFloat()、parseInt() 等

(3)基本对象,基本对象是定义或使用其他对象的基础。基本对象包括一般对象、函数对象和错误对象。例如 Object、Function、Boolean、Symbol、Error 等

(4)数字和日期对象,用来表示数字、日期和执行数学计算的对象。例如 Number、Math、Date

(5)字符串,用来表示和操作字符串的对象。例如 String、RegExp

(6)可索引的集合对象,这些对象表示按照索引值来排序的数据集合,包括数组和类型数组,以及类数组结构的对象。例如 Array

(7)使用键的集合对象,这些集合对象在存储数据时会使用到键,支持按照插入顺序来迭代元素。 例如 Map、Set、WeakMap、WeakSet

(8)矢量集合,SIMD 矢量集合中的数据会被组织为一个数据序列。 例如 SIMD 等

(9)结构化数据,这些对象用来表示和操作结构化的缓冲区数据,或使用 JSON 编码的数据。例如 JSON 等

(10)控制抽象对象 例如 Promise、Generator 等

(11)反射。例如 Reflect、Proxy

(12)国际化,为了支持多语言处理而加入 ECMAScript 的对象。例如 Intl、Intl.Collator 等

(13)WebAssembly

(14)其他。例如 arguments

8.什么是 DOM 和 BOM?(能大概说出来就好了)
  • DOM 指的是文档对象模型,它指的是把文档当做一个对象,这个对象主要定义了处理网页内容的方法和接口。
  • BOM 指的是浏览器对象模型,它指的是把浏览器当做一个对象来对待,这个对象主要定义了与浏览器进行交互的法和接口。BOM的核心是 window,而 window 对象具有双重角色,它既是通过 js 访问浏览器窗口的一个接口,又是一个 Global(全局)对象。这意味着在网页中定义的任何对象,变量和函数,都作为全局对象的一个属性或者方法存在。window 对象含有 location 对象、navigator 对象、screen 对象等子对象,并且 DOM 的最根本的对象 document 对象也是 BOM 的 window 对象的子对象。
9.ES6模块与CommonJS模块有什么异同?

ES6 Module和CommonJS模块的区别:

  • CommonJS是对模块的浅拷⻉,ES6 Module是对模块的引⽤,即ES6 Module只存只读,不能改变其值,也就是指针指向不能变,类似const;
  • import的接⼝是read-only(只读状态),不能修改其变量值。 即不能修改其变量的指针指向,但可以改变变量内部指针指向,可以对commonJS对重新赋值(改变指针指向),但是对ES6 Module赋值会编译报错。

ES6 Module和CommonJS模块的共同点:

  • CommonJS和ES6 Module都可以对引⼊的对象进⾏赋值,即对对象内部属性的值进⾏改变。
10.对原型、原型链的理解

在JavaScript中是使用构造函数来新建一个对象的,每一个构造函数的内部都有一个 prototype 属性,它的属性值是一个对象,这个对象包含了可以由该构造函数的所有实例共享的属性和方法。当使用构造函数新建一个对象后,在这个对象的内部将包含一个指针,这个指针指向构造函数的 prototype 属性对应的值,在 ES5 中这个指针被称为对象的原型。一般来说不应该能够获取到这个值的,但是现在浏览器中都实现了 proto 属性来访问这个属性,但是最好不要使用这个属性,因为它不是规范中规定的。ES5 中新增了一个 Object.getPrototypeOf() 方法,可以通过这个方法来获取对象的原型。

当访问一个对象的属性时,如果这个对象内部不存在这个属性,那么它就会去它的原型对象里找这个属性,这个原型对象又会有自己的原型,于是就这样一直找下去,也就是原型链的概念。原型链的尽头一般来说都是 Object.prototype 所以这就是新建的对象为什么能够使用 toString() 等方法的原因。

特点: JavaScript 对象是通过引用来传递的,创建的每个新对象实体中并没有一份属于自己的原型副本。当修改原型时,与之相关的对象也会继承这一改变。

img

11.对闭包的理解,使用场景,有啥缺陷:

闭包:让你可以在一个内层函数中访问到其外层函数的作用域, 在 JavaScript中,每当创建一个函数,闭包就会在函数创建的同时被创建出来,作为函数内部与外部连接起来的一座桥梁

function init() {
    var name = "Mozilla"; // name 是一个被 init 创建的局部变量
    function displayName() { // displayName() 是内部函数,一个闭包
        alert(name); // 使用了父函数中声明的变量
    }
    displayName();
}
init();

displayName() 没有自己的局部变量。然而,由于闭包的特性,它可以访问到外部函数的变量

使用场景

任何闭包的使用场景都离不开这两点:

  • 创建私有变量
  • 延长变量的生命周期 一般函数的词法环境在函数返回后就被销毁,但是闭包会保存对创建时所在词法环境的引用,即便创建时所在的执行上下文被销毁,但创建时所在词法环境依然存在,以达到延长变量的生命周期的目的
柯里化函数(很少问到,有点小恶心人,第一次面试就遇到这个问题,结果懵了)

柯里化的目的在于避免频繁调用具有相同参数函数的同时,又能够轻松的重用

// 假设我们有一个求长方形面积的函数
function getArea(width, height) {
    return width * height
}
// 如果我们碰到的长方形的宽老是10
const area1 = getArea(10, 20)
const area2 = getArea(10, 30)
const area3 = getArea(10, 40)

// 我们可以使用闭包柯里化这个计算面积的函数
function getArea(width) {
    return height => {
        return width * height
    }
}

const getTenWidthArea = getArea(10)
// 之后碰到宽度为10的长方形就可以这样计算面积
const area1 = getTenWidthArea(20)

// 而且如果遇到宽度偶尔变化也可以轻松复用
const getTwentyWidthArea = getArea(20)
12.哪些情况会导致内存泄漏

以下四种情况会造成内存的泄漏:

  • 意外的全局变量: 由于使用未声明的变量,而意外的创建了一个全局变量,而使这个变量一直留在内存中无法被回收。
  • 被遗忘的计时器或回调函数: 设置了 setInterval 定时器,而忘记取消它,如果循环函数有对外部变量的引用的话,那么这个变量会被一直留在内存中,而无法被回收。
  • 脱离 DOM 的引用: 获取一个 DOM 元素的引用,而后面这个元素被删除,由于一直保留了对这个元素的引用,所以它也无法被回收。
  • 闭包: 不合理的使用闭包,从而导致某些变量一直被留在内存当中。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值