javascript面试题的简单整理(第一部分)

js一些面试资料的整理

一. 性能优化(减少请求次数)

图片处理

  • 雪碧图
  • Base64
  • 使用字体图标代替图片
  • 在安卓下可以使用webp格式图片

减少资源大小

  • HTML压缩
  • CSS压缩
  • JS压缩与混乱
  • 图片压缩

优化网络连接

  • CDN(Content Delivery Network)内容分发网络,它能够实时地根据网络流量和各节点的连接、负载状
    况以及到用户的距离和响应时间等综合信息将用户的请求重新导向离用户最近的服务节点上。其目的是使用户可就近取得所需内容,解决 Internet网络拥挤的状况,提高用户访问网站的响应速度

优化资源加载

  • 资源加载位置:
    通过优化资源加载位置,更改资源加载时机,使尽可能快地展示出页面内容,尽可能快地使功能可用
    1、CSS文件放在head中,先外链,后本页
    2、JS文件放在body底部,先外链,后本页
    3、body中间尽量不写style标签和script标签

  • 资源加载时机:
    1、异步script标签
    defer: 异步加载,在HTML解析完成后执行。defer的实际效果与将代码放在body底部类似。
    async: 异步加载,加载完成后立即执行。
    2、模块按需加载
    按需加载,是一种很好的优化网页或应用的方式。这种方式实际上是先把代码在一些逻辑断点处分离开,然后在一些代码块中完成某些操作后,立即引用或即将引用另外一些新的代码块。这样加快了应用的初始加载速度,减轻了它的总体体积,因为某些代码块可能永远不会被加载
    3、资源懒加载与资源预加载
    资源懒加载和资源预加载都是一种错峰操作,在浏览器忙碌的时候不做操作,浏览器空间时,再加载资源,优化了网络性能

减少重绘回流

  • 重绘:当render tree中的一些元素需要更新属性,而这些属性只是影响元素的外观,风格,而不会影响布局的,比如background-color。
  • 回流:当render tree中的一部分(或全部)因为元素的规模尺寸,布局,隐藏等改变而需要重新构建。
  • 回流必将引起重绘,而重绘不一定会引起回流。

优化方法:

  • 最小化重绘和重排
    • 使用cssText
    • 修改CSS的class
  • 批量修改DOM
    • 使元素脱离文档流
    • 对其进行多次修改
    • 将元素带回到文档中。

避免触发同步布局事件 - 获取元素存储(多个标签)
对于复杂动画效果,使用绝对定位让其脱离文档流
css3硬件加速(GPU加速)

样式设置:
1、避免使用层级较深的选择器,或其他一些复杂的选择器,以提高CSS渲染效率。
2、避免使用CSS表达式,CSS表达式是动态设置CSS属性的强大但危险方法,它的问题就在于计算频率很快。不仅仅是在页面显示和缩放时,就是在页面滚动、乃至移动鼠标时都会要重新计算一次.
3、元素适当地定义高度或最小高度,否则元素的动态内容载入时,会出现页面元素的晃动或位置,造成回流.
4、给图片设置尺寸。如果图片不设置尺寸,首次载入时,占据空间会从0到完全出现,上下左右都可能位移,发生回流.
5、不要使用table布局,因为一个小改动可能会造成整个table重新布局。而且table渲染通常要3倍于同等元素时间
6、能够使用CSS实现的效果,尽量使用CSS而不使用JS实现

DOM优化

  • 缓存DOM
  • 减少DOM深度及DOM数量
  • 批量操作DOM
  • 批量操作CSS样式
  • 在内存中操作DOM
  • DOM元素离线更新
  • DOM读写分离
  • 事件代理
  • 防抖和节流
  • 及时清理环境

二. 类(构造函数)

类的概念

类就是一类事物,而对象就是一个事物,一类事物中包含若干的事物(而这其中的具体的事物就是对象)

类和对象

类是对象的抽象,而对象是类的具体实例。类是抽象的,不占用内存,而对象是具体的,占用存储空间。类是用于创建对象的,它是一个定义包括在特定类型的对象中的方法和变量的软件模板。

构造函数

构造函数:其实就是一个普通函数,但是内部使用了this变量。对构造函数使用new运算符,就能生成实例对象,并且this变量会绑定在实例对象上。
构造函数的基本特点:首字母大写 new运算符实例化对象。
构造函数弊端:构造函数里面的属性和方法都是私有的(根据开发习惯,属性私有是正常的,而方法必须是公有为主)

原型(prototype):每一个函数都有一个原型对象(属性对象),原型上面绑定是公有的属性或者方法,而且里面的this依然指向实例对象。

以 new 操作符调用函数的时候,函数内部发生以下变化:
1、创建一个空对象,并且 this 变量引用该对象,同时还继承了该函数的原型。
2、属性和方法被加入到 this 引用的对象中。
3、并且最后隐式的返回 this (创建也是隐式)。

三.变量的类型及其检测

基本类型(6)

  • number
  • string
  • boolean
  • undefined
  • null
  • symbol(es6新加)

引用类型(1) object

  • object

最好的检测数据类型的方式

  • typeof:查看类型
  • instanceof:从属关系
  • constructor:实例对象的类(构造函数)
  • toString:转字符串、进制转换、类型判断(最好的方法) Object.prototype.toString.call()

四.运算符优先级

赋值、数学、关系运算符的讲解

  • 赋值运算符 = 将等式右边的结果赋值给左边,用来给变量或者属性赋值。(最低优先级)
  • 复合赋值操作 +=、-=、*=、/=、%= 带操作的复合赋值运算。(更快捷,更优)。
  • 数学运算符 + - * / %
  • +:求和,连接字符作用(字符串和变量之间使用+号进行拼接)
  • %:求余数(求模)
  • 关系运算符(结果为布尔值) <、>、<=、>=、= =( 相等 )、= = =(全等)、!=(不相等) !==(不全等)

逻辑运算符:&& 与、|| 或、! 非

  • 逻辑与(&&)操作可以应用于任何类型的操作数,而不仅仅是布尔值。在有一个操作数不是布尔值的情况下,逻辑与操作就不一定返回布尔值。逻辑与操作属于短路操作,即如果第一个操作数能够决定结果,那么就不会再对第二个操作数求值。
  • 逻辑或(||)和逻辑与操作相似,如果有一个操作数不是布尔值,逻辑或也不一定返回布尔值,逻辑或操作符也是短路操作符。也就是说,如果第一个操作数的求值结果为true ,就不会对第二个操作数求值了。
  • 逻辑非操作符由一个叹号(!)表示,可以应用于 ECMAScript 中的任何值。无论这个值是什么数据类型,这个操作符都会返回一个布尔值。逻辑非操作符首先会将它的操作数转换为一个布尔值,然后再对其求反。

一元运算符:++ 和 –

只能操作一个值的操作符叫做一元操作符,是 ECMAScript 中最简单的操作符。
前置型应该位于要操作的变量之前,先将操作数+1或者减1,再参与运算。
后置型则应该位于要操作的变量之后,先参与运算后自身再+1或者减1。

五.for…of与其他遍历语法的比较

for循环这种写法比较麻烦,因此数组提供内置的forEach方法。forEach没有返回值,无法中途跳出forEach循环,break命令或return命令都不能奏效。

for…in循环有几个缺点。数组的键名是数字,但是for…in循环是以字符串作为键名“0”、“1”、“2”等等。for…in循环不仅遍历数字键名,还会遍历手动添加的其他键,甚至包括原型链上的键。某些情况下,for…in循环会以任意顺序遍历键名。总之,for…in循环主要是为遍历对象而设计的,不适用于遍历数组

for…of循环相比上面几种做法,有一些显著的优点。有着同for…in一样的简洁语法,但是没有for…in那些缺点。不同于forEach方法,它可以与break、continue和return配合使用。提供了遍历所有数据结构的统一操作接口。

六.作用域

任何程序设计语言都有作用域的概念,简单的说,作用域就是变量与函数的可访问范围,即作用域控制着变量与函数的可见性和生命周期。

1.局部作用域和全局作用域

在JavaScript中,变量的作用域有全局作用域和局部作用域两种。

  • 全局作用域(变量):整个程序都有效,即整个代码中都可以调用(变量前面没有添加var变成全局的属性)
  • 局部作用域(变量):只对函数内部有效,即只能在本变量声明的函数内部调用。

2.作用域链

通俗地讲,当声明一个函数时,局部作用域一级一级向上包起来,就是作用域链。

当执行函数时,总是先从函数内部找寻局部变量如果内部找不到(函数的局部作用域没有),则会向创建函数的作用域(声明函数的作用域)寻找,依次向上查找。在函数体内,局部变量的优先级高于同名的全局变量-作用域链

3.JS的编译和执行

JS的解析过程分为两个阶段:预编译期(预处理)与执行期。

第一阶段(预编译期): JS会对本代码块(script)中的所有声明的变量和函数进行处理(类似与 C语言的编译),但需要注意的是此时处理函数的只是声明式函数,而且变量也只是进行了声明但未进行初始化以及赋值。

  • 先找var和function关键字,如果找到var关键字,提前赋值undefined给变量名. 如果找到function,提前将整个函数赋值给函数名称。
  • 如果函数和变量出现重名,函数优先。
  • 函数的参数类似于变量,函数内部同样做预解析,支持预解析。
  • if语句和for语句里面的变量和函数做预解析提前赋值undefined,函数声明不会跳过。

第二阶段(执行期):在编译后的基础上开始从上到下执行脚本,遇到错误时中断。

七.转化数组的方式

  • Array.from()
  • 扩展运算符(…)
  • Array.prototype.slice.call()

八.数组排序(手写)

  • 冒泡排序
    在这里插入图片描述

  • 选择排序
    在这里插入图片描述

  • 快速排序
    在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值