----- 前端面试题 -----

HTML5新增的元素

首先html5为了更好的实践web语义化,增加了header,footer,nav,aside,section等语义化标签,在表单方面,为了增强表单,为input增加了color,emial,data ,range等类型,在存储方面,提供了sessionStorage,localStorage,和离线存储,通过这些存储方式方便数据在客户端的存储和获取,在多媒体方面规定了音频和视频元素audio和vedio,另外还有地理定位,canvas画布,拖放,多线程编程的web worker和websocket协议

css

常用的布局

  • 静态布局

    宽高固定

  • 自适应布局

    布局特点:不同分辨率下,页面元素位置变化,大小不变

    实现方法:针对不同分辨率创建对应的样式表,使用 @media 媒体查询给不同尺寸的设备切换不同的样式

    缺点:IE8及以下不支持媒体查询;只能兼容主流分辨率

  • 流式布局(百分比布局):

    布局特点:不同的分辨率下显示相同的排版;高度固定,宽度自适应

    实现方法:网页中主要区域的尺寸使用百分比;

    缺点:大屏幕上元素被拉长,但是文字,高度还是固定大小,不协调

        经典流式布局:左侧固定,右侧自适应;两侧固定,中间自适应

  • 弹性布局(rem/em布局)

    布局特点:页面元素宽度,高度,字体大小会跟着屏幕大小缩放

    实现方法:使用js监听当前屏幕大小,设置html的字体大小

    缺点:IE678不兼容;需要计算;

  • 响应式布局

    布局特点:每个屏幕分辨率下面会有一个布局样式,即元素位置和大小都会变,响应式设计的目标是确保一个页面在所有终端上(各种尺寸的PC、手机、手表等等)都能显示出令人满意的效果

    实现方法:媒体查询+流式布局

    优点:适应pc和移动端

    缺点:要匹配足够多的屏幕大小,工作量大,设计也需要多个版本

css3新特性

1.过渡 transition 2.动画 animation 3.形状转换 transform 4.阴影 box-shadow 5.滤镜 Filter 6.颜色 rgba 7.栅格布局 gird 8.弹性布局 flex

伪类与伪元素区别

1)伪类(pseudo-classes)

  • 其核⼼就是⽤来选择DOM树之外的信息,不能够被普通选择器选择的⽂档之外的元素,⽤来添加⼀些选择器的特殊效果。

  • ⽐如:hover :active :visited :link :visited :first-child :focus :lang等

  • 由于状态的变化是⾮静态的,所以元素达到⼀个特定状态时,它可能得到⼀个伪类的样式;当状态改变时,它⼜会失去这个样式。

  • 由此可以看出,它的功能和class有些类似,但它是基于⽂档之外的抽象,所以叫 伪类。

2)伪元素(Pseudo-elements)

  • DOM树没有定义的虚拟元素

  • 核⼼就是需要创建通常不存在于⽂档中的元素,

  • ⽐如::before ::after 它选择的是元素指定内容,表示选择元素内容的之前内容或之后内容。

  • 伪元素控制的内容和元素是没有差别的,但是它本身只是基于元素的抽象,并不存在于⽂档中,所以称为伪元素。⽤于将特殊的效果添加到某些选择器

2)伪类与伪元素的区别

  • 表示⽅法

    • CSS2 中伪类、伪元素都是以单冒号:表示,

    • CSS2.1 后规定伪类⽤单冒号表示,伪元素⽤双冒号::表示,

    • 浏览器同样接受 CSS2 时代已经存在的伪元素(:before, :after, :first�line, :first-letter 等)的单冒号写法。

    • CSS2 之后所有新增的伪元素(如::selection),应该采⽤双冒号的写法。

    • CSS3中,伪类与伪元素在语法上也有所区别,伪元素修改为以::开头。浏览器对以:开头的伪元素也继续⽀持,但建议规范书写为::开头

  • 定义不同

    • 伪类即假的类,可以添加类来达到效果

    • 伪元素即假元素,需要通过添加元素才能达到效果

  • 总结:

    • 伪类和伪元素都是⽤来表示⽂档树以外的"元素"。

    • 伪类和伪元素分别⽤单冒号:和双冒号::来表示。

    • 伪类和伪元素的区别,关键点在于如果没有伪元素(或伪类),

    • 是否需要添加元素才能达到效果,如果是则是伪元素,反之则是伪类。

4)相同之处:

  • 伪类和伪元素都不出现在源⽂件和DOM树中。也就是说在html源⽂件中是看不到伪类和伪元素的。 不同之处:

  • 伪类其实就是基于普通DOM元素⽽产⽣的不同状态,他是DOM元素的某⼀特征。

  • 伪元素能够创建在DOM树中不存在的抽象对象,⽽且这些抽象对象是能够访问到的。

让一个div水平垂直居中

  • 使用position + transform

  • 使用flex

  • 使用position

  • 使用伪类

    .parent{
        font-size: 0;
        text-align: center;
    }
    .parent::before {
        content: "";
        display: inline-block;
        width: 0;
        height: 100%;
        vertical-align: middle;
    }
    .child{
        display: inline-block;
        vertical-align: middle;
    }

link和@import有什么区别

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

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

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

js

数组和对象的原生方法

  • Array

    • Array.concat( ) 合并数组

    • Array.join( ) 将数组元素连接起来以构建一个字符串

    • Array.length 数组的大小

    • Array.pop( ) 删除最后一项,返回所删除的值

    • Array.shift( ) 删除第一项,返回所删除的值

    • Array.push( ) 往数组最后插入数据,返回数组的长度

    • Array.unshift( ) 在数组头部插入数据,返回数组的长度

    • Array.reverse( ) 倒叙

    • Array.slice( ) 截取子数组,返回新值

    • Array.sort( ) 对数组元素进行排序

    • Array.splice( ) 插入、删除或替换数组的元素

    • Array.toLocaleString( ) 把数组转换成局部字符串

    • Array.toString( ) 将数组转换成一个字符串

    • Array.indexof( ) 检测数据中是否含有某个数据

    • Array.forEach( ) 循环数组

  • Object

    • Object.hasOwnProperty( ) 检查属性是否被继承

    • Object.isPrototypeOf( ) 一个对象是否是另一个对象的原型

    • Object.propertyIsEnumerable( ) 是否可以通过for/in循环看到属性

    • Object.toLocaleString( ) 返回对象的本地字符串表示

    • Object.toString( ) 定义一个对象的字符串表示

    • Object.valueOf( ) 指定对象的原始值

  • ES6

    • Array.from() 将类数组对象或可迭代对象转化为数组。

    • Array.of() 形成新数组,

    • map() 遍历数组,返回一个新数组,不改变原数组

    • filter() 过滤掉数组中不满足条件的值,返回一个新数组,不改变原数组。

    • reduce() 让数组的前后两项进行某种计算,然后返回其值,并继续计算,不改变原数组,返回计算的最终结果。

    • some() 用于遍历数组每一项,有一项返回true,则停止遍历,结果返回true。不改变原数组

    • every() 用于遍历数组每一项,每一项返回true,最终结果为true.有一项返回false,停止遍历,结果返回为false。不改变原数组。

    • find() 方法找到第一个符合条件的成员,没有符合的则返回 undefined

    • findIndex 方法的用法与 find方法非常类似,返回第一个符合条件的数组成员的位置,如果所有成员都不符合条件,则返回-1。

    • fill() 方法使用给定值, 填充一个数组,fill 方法还可以接受第二个和第三个参数,用于指定填充的起始位置和结束位置

    • copyWithin() 将一定范围索引的数组元素修改为此数组另一指定范围索引的元素

    • includes() 数组是否包含指定值,返回布尔值

    • entries(),keys()和 values()——用于遍历数组,可以用 for...of 循环进行遍历,唯一的区别是 keys(是对键名的遍历、values()是对键值的遍历,entries()是对键值对的遍历 foreach() 用于遍历数组,无返回值,不改变原数组,仅仅只是遍历,常用于注册组件、指令等等

内存泄漏

内存泄露

  • 指由于疏忽或错误造成程序未能释放已经不再使用的内存的情况。内存泄漏并非指内情人q存在物理上的消失,而是应用程序分配某段内存后,由于设计错误,失去了对该段内存的控制,因而造成了内存的浪费

  • 排查

    一)是否App中的类中和引用变量过多使用了Static修饰 如public staitc Student s;在类中的属性中使用 static修饰的最好只用基本类型或字符串。如public static int i = 0; //public static String str;

    二)是否App中使用了大量的递归或无限递归(递归中用到了大量的建新的对象)

    三)是否App中使用了大量循环或死循环(循环中用到了大量的新建的对象)

    四)检查App中是否使用了向数据库查询所有记录的方法。即一次性全部查询的方法,如果数据量超过10万多条了,就可能会造成内存溢出。所以在查询时应采用“分页查询”。

    五)检查是否有数组,List,Map中存放的是对象的引用而不是对象,因为这些引用会让对应的对象不能被释放。会大量存储在内存中。

    六)检查是否使用了“非字面量字符串进行+”的操作。因为String类的内容是不可变的,每次运行"+"就会产生新的对象,如果过多会造成新String对象过多,从而导致JVM没有及时回收而出现内存溢出。

内存溢出

  • 内存溢出是由于没被引用的对象(垃圾)过多造成JVM没有及时回收,造成的内存溢出

  • 引起内存溢出的原因

    1. 内存中加载的数据量过于庞大,如一次从数据库取出过多数据;

    2. 集合类中有对对象的引用,使用完后未清空,使得JVM不能回收;

    3. 代码中存在死循环或循环产生过多重复的对象实体;

    4. 使用的第三方软件中的BUG;

    5. 启动参数内存值设定的过小

写JavaScript的基本规范

  1. 不要在同一行声明多个变量。

  2. 请使用 ===/!==来比较true/false或者数值

  3. 使用对象字面量替代new Array这种形式

  4. 不要使用全局函数。

  5. Switch语句必须带有default分支

  6. 函数不应该有时候有返回值,有时候没有返回值。

  7. For循环必须使用大括号

  8. If语句必须使用大括号

  9. for-in循环中的变量 应该使用var关键字明确限定作用域,从而避免作用域污染。

JS的数据类型

基本类型:Number、Boolean、String、null、undefined、symbol(ES6 新增的),BigInt(ES2020) 引用类型:Object,对象子类型(Array,Function)

浅拷贝和深拷贝的区别

  • 浅拷贝:一般指的是把对象的第一层拷贝到一个新对象上去

  • 深拷贝:一般需要借助递归实现,如果对象的值还是个对象,要进一步的深入拷贝,完全替换掉每一个复杂类型的引用。

浅拷贝:浅拷贝通过ES6新特性Object.assign()或者通过扩展运算法...来达到浅拷贝的目的,浅拷贝修改 副本,不会影响原数据,但缺点是浅拷贝只能拷贝第一层的数据,且都是值类型数据,如果有引用型数据,修改 副本会影响原数据。

深拷贝:通过利用JSON.parse(JSON.stringify())来实现深拷贝的目的,但利用JSON拷贝也是有缺点的, 当要拷贝的数据中含有undefined/function/symbol类型是无法进行拷贝的,当然我们想项目开发中需要 深拷贝的数据一般不会含有以上三种类型,如有需要可以自己在封装一个函数来实现。

事件监听

addEventListener()方法,用于向指定元素添加事件句柄,它可以更简单的控制事件,语法为

element.addEventListener(event, function, useCapture);

第一个参数是事件的类型(如 "click" 或 "mousedown").

第二个参数是事件触发后调用的函数。

第三个参数是个布尔值用于描述事件是冒泡还是捕获。该参数是可选的。

事件传递有两种方式,冒泡和捕获

事件传递定义了元素事件触发的顺序,如果你将P元素插入到div元素中,用户点击P元素,

在冒泡中,内部元素先被触发,然后再触发外部元素,

捕获中,外部元素先被触发,在触发内部元素,

事件委托以及冒泡原理

事件委托是利用冒泡阶段的运行机制来实现的,就是把一个元素响应事件的函数委托到另一个元素,一般是把一组元素的事件委托到他的父元素上,委托的优点是

减少内存消耗,节约效率

动态绑定事件

事件冒泡,就是元素自身的事件被触发后,如果父元素有相同的事件,如onclick事件,那么元素本身的触发状态就会传递,也就是冒到父元素,父元素的相同事件也会一级一级根据嵌套关系向外触发,直到document/window,冒泡过程结束。

事件冒泡和事件捕获

事件捕获(event capturing): 当鼠标点击或者触发dom事件时(被触发dom事件的这个元素被叫作事件源),浏览器会从根节点到事件源(由外到内)进行事件传播。

事件冒泡(dubbed bubbling):事件冒泡刚好相反,事件源到根节点(由内到外)进行事件传播。

无论是事件捕获还是事件冒泡,它们都有一个共同的行为,就是事件传播。dom标准事件流的触发的先后顺序为:先捕获再冒泡。即当触发dom事件时,会先进行事件捕获,捕获到事件源之后通过事件传播进行事件冒泡。

在我们平常用的addEventListener方法中,一般只会用到两个参数,一个是需要绑定的事件,另一个是触发事件后要执行的函数,然而,addEventListener还可以传入第三个参数,第三个参数默认值是false,表示在事件冒泡阶段调用事件处理函数;如果参数为true,则表示在事件捕获阶段调用处理函数。

JS中的垃圾回收机制

一、为什么要垃圾回收

如果没有垃圾回收机制,适时清理不被引用的值并释放相应的内存空间,JavaScript 解释器将会消耗完系统中所有可用内存,造成系统崩溃。

二、垃圾回收的核心思路

所谓垃圾回收的核心思想就是清理掉内存中不再被引用的值,通俗的说,就是清理掉内存中没用的值,那么如何判断有没有用?如果是局部变量,在函数调用结束后即是无用的,可以被回收掉;而全局变量在浏览器卸载页面的时候才会消失。由于这个过程消耗较大,所以解释器会按照固定时间周期性的执行回收。

三、垃圾回收的两种方式

1.标记清除(JS最常用)

标记清除法主要有以下三个步骤:

1)给所有变量增加一个标记,如果是进入执行环境(比如申明变量),则标记为“进入环境”,如果是结束执行环境(比如执行完相关函数),则标记为“离开环境”;

2)去掉“进入环境”的变量标记以及被该变量所引用的变量标记(比如闭包);

3)还存在标记的变量即是需要被清理的变量。

2.引用计数

引用计数法主要有以下三个步骤:

1)申明了一个变量,并且将一个引用类型的值赋值给这个变量,那么这变量的引用就加1;

2)如果这个变量的值又指向另外一个值,或者说这个变量被重新赋值了,那么以上的引用类型的值的引用次数就减1;

3)如此一来,该引用类型的值的引用次数即为0,垃圾回收器会在运行的时候清理掉引用次数为0的值并释放相应的内存空间;

4)特别注意:引用计数在代码中存在循环引用时会出现问题

判断数组的方法

Object.prototype.toString.call()、instanceof、Array.isArray()以及typeof

面向对象

面向对象的三大特性:继承/多态/封装

  • 封装

    封装最好理解了。封装是面向对象的特征之一,是对象和类概念的主要特性。封装,也就是把客观事物封装成抽象的类,并且类可以把自己的数据和方法只让可信的类或者对象操作,对不可信的进行信息隐藏。

  • 继承

    继承是指这样一种能力:它可以使用现有类的所有功能,并在无需重新编写原来的类的情况下对这些功能进行扩展。通过继承创建的新类称为“子类”或“派生类”,被继承的类称为“基类”、“父类”或“超类”。

    要实现继承,可以通过“继承”(Inheritance)和“组合”(Composition)来实现。

  • 多态性

    多态性(polymorphisn)是允许你将父对象设置成为和一个或更多的他的子对象相等的技术,赋值之后,父对象就可以根据当前赋值给它的子对象的特性以不同的方式运作。简单的说,就是一句话:允许将子类类型的指针赋值给父类类型的指针。

    实现多态,有两种方式,覆盖和重载。覆盖和重载的区别在于,覆盖在运行时决定,重载是在编译时决定。并且覆盖和重载的机制不同,例如在 Java 中,重载方法的签名必须不同于原先方法的,但对于覆盖签名必须相同。

作用域链

全局函数无法查看局部函数的内部细节,但局部函数可以查看其上层的函数细节,直至全局细节。 当需要从局部函数查找某

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值