1.HTML和HTML5有什么区别?
什么是HTML5?
HTML5 将成为 HTML、XHTML 以及 HTML DOM 的新标准
1.文档类型声明
HTML
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3333.org/TR/html4/
strict.dtd">
HTML5
<!DOCTYPE html>
可以看出:HTML的文档类型声明太长而且复杂,而HTML5的文档声明相对来说更为简便,有利于程序员快速阅读和开发
2.音频和视频的支持
HTML如果不使用Flash播放器支持,它不支持音频和视频。HTML5使用audio和video标签来支持音频和视频控制
3.图形的支持
svg、canvas绘图
4.新增了一些语义化元素和移除元素
新增
article、nav、details、footer、header、main、time、canvas、svg、audio、video等标签
移除
font、center、u、big、strike、tt等标签
5.会话存储和本地存储
localStorage、sessionStorage
2.什么是盒子模型?
可以把所有HTML标签都理解成一个盒子模型
盒子模型主要由4个部分组成:content、padding、border、margin
- 标准盒模型(W3C盒模型) content-box 盒子的尺寸 = content
- 怪异盒模型(IE盒模型) border-box 盒子的尺寸 = content + padding + border
3.如何理解HTML5语义化?
什么是标签语义化?
提升代码可读性,便于团队开发和维护
为什么要标签语义化?
当网页去掉CSS样式时,页面能呈现出来清晰的结构
4.cookies、sessionStorage、localStorage的区别是什么?
存储大小
- cookie:数据大小不能超过4k
- localStorage、sessionStorage:数据大小支持5M左右,不同浏览器存储大小不同
生命周期(有效时间)
- cookie:需要设置有效期,过期后cookie就会销毁
- localStorage:除非被手动清理,否则永久存在
- sessionStorage:页面关闭(包括标签选项卡)后就会被销毁
存储形式
- 三者都是存储字符串类型,复杂对象可以采用json的stringify和parse方法来做处理
安全性
-
cookie:请求时一般会携带在header中
-
ocalStorage、sessionStorage:请求时不会携带
5.常见的浏览器内核有哪些?
什么是浏览器内核?
- 浏览器内核也可以理解为排版引擎,主要由2部分组成,渲染引擎和 JS 引擎
- 排版引擎主要是负责获取网页内容(HTML、XML、图像、CSS、JS)等信息进行解析、渲染网页,将网页的代码转换为看得到的页面
- 浏览器的内核的不同对于网页的语法解释会有不同,所以渲染的效果也不相同,常见的内核有Trident、 Gecko、 Webkit、
Presto、 Blink五种
Trident内核
代表作品是IE,俗称IE内核;使用IE内核的浏览器包括、傲游、世界之窗、百度浏览器、兼容模式的浏览器等
WebKit内核
代表作品是Safari、旧版的Chrome
Presto内核
代表作品是Opera,Presto是由Opera Software开发的浏览器排版引擎,它是世界公认最快的渲染速度的引擎。在13年之后,Opera宣布加入谷歌阵营,弃用了 Presto
Blink内核
代表作品是Chrome、Opera;由Google和Opera Software开发的浏览器排版引擎
Gecko内核
代表作品是Firefox,俗称Firefox内核
Chromium内核
这个比较特殊,Chromium是谷歌的开源项目是一款浏览器,Chrome 是Chromium的稳定版。国内的大部分双核浏览器都采用Chromium内核
6.谈谈你对web标准以及W3C的理解?
web标准
web标准主要分为结构、表现、行为3部分
- 结构:指我们平时在body里面写的标签,主要是由HTML标签组成
- 表现:指更加丰富HTML标签样式,主要由CSS样式组成
- 行为:指页面和用户的交互,主要由JS部分组成
W3C
W3C对web标准提出了规范化的要求,即代码规范
对结构的要求
- 标签字母要小写
- 标签要闭合
- 标签不允许随意嵌套
对表现和行为的要求
- 建议使用外链CSS和js脚本,实现结构与表现分离、结构与行为分离,能提高页面的渲染效率,更快地显示网页内容
7.在浏览器中输入URL后,执行的过程?
这个题目没有标准答案,以下是我个人的理解
- 浏览器通过DNS查找域名的IP地址
- 浏览器与目标服务器建立TCP连接(3次握手)
- 浏览器通过http协议发送资源请求(接口、图片、音频、视频、CSS、JS等等)
- 服务器端响应http请求
- 浏览器解析渲染HTML代码,最终呈现给用户
- 关闭页面,释放TCP连接(4次挥手)
8.如何实现浏览器响应式布局?
- 使用flex弹性布局
- 使用媒体查询(@media)
- 使用百分比单位
- 使用REM单位
- 使用VW、VH单位
9.XHTML和HTML有什么区别?
主要是体现在代码规范上,XHTML规范会更加严格
XHTML 元素必须被正确地嵌套
- 正确示范
<b><i>This text is bold and italic</i></b>
- 错误示范
<b><i>This text is bold and italic</b></i>
XHTML 元素必须被关闭
- 正确示范
<p>This is a paragraph</p>
<p>This is another paragraph</p>
A break: <br />
A horizontal rule: <hr />
An image: <img src="happy.gif" alt="Happy face" />
- 错误示范
<p>This is a paragraph
<p>This is another paragraph
A break: <br>
A horizontal rule: <hr>
An image: <img src="happy.gif" alt="Happy face">
标签名必须用小写字母
- 正确示范
<body>
<p>This is a paragraph</p>
</body>
- 错误示范
<BODY>
<P>This is a paragraph</P>
</BODY>
XHTML 文档必须拥有根元素
- 所有的 XHTML 元素必须被嵌套于 根元素中
<html>
<head> ... </head>
<body> ... </body>
</html>
10.谈谈你对静态布局、自适应布局、响应式布局、弹性布局、流式布局的理解?
静态布局
- 描述:就是设定好的长和宽,大小不会改变,不管你多大的屏幕它都是那么大,分辨率是不会改变的
- 优点:这个对于开发者来说是最简单的一种布局方式,没有什么兼容性的问题
- 缺点:当屏幕分辨率太低时,会展现出滚动条
- 场景:传统web网站
自适应布局
- 描述:不同屏幕分辨率下,保持原有展示方式。元素的尺寸大小可以改变,但展示方式不会改变
- 优点:页面能够兼容不同分辨率的设备
- 缺点:屏幕太小会发生内容过于拥挤。所有的设备看起来都是一样的网站,不过是长度或者图片变小了,不会根据设备采用不同的展示样式
- 场景:主要兼容PC端不同分辨率设备
响应式布局
- 描述:不同屏幕分辨率下,展示方式不同
- 优点:一套代码兼容web端、平板、以及手机端网页
- 缺点:工作量大、UI设计也需要多个版本
- 场景:同时兼容多种不同设备
弹性布局(em/rem布局)
- 描述:使用 em 或 rem 单位进行相对布局,在不同屏幕分辨率下页面所有元素的高宽都等比例缩放
- 优点:所有屏幕的高宽比和最初的设计高宽比一样,或者相差不多,完美适应
- 缺点:这种布局方式只是宽度自适应,高度却没有做到自适应
- 场景:同时兼容多种不同设备
弹性布局(flex布局)
- 描述:目前比较流行的一种布局,使用传统布局难以实现一些复杂的布局,使用flex布局实现就变得非常容易
- 优点:简便、完整、响应式地实现各种页面布局
- 缺点:只兼容IE10+的浏览器
- 场景:三栏式布局、垂直水平居中布局
流式布局(百分比布局)
- 描述:页面元素的宽度按照屏幕分辨率进行适配调整,但整体布局不变。主要特征是像瀑布一样往下流,有规律的无限遍历模块。
- 优点:灵活,充分利用浏览器的空间
- 缺点:宽度按照屏幕进行适配调整,对于大屏幕来说用户体验并不是特别好,有些布局元素会显得很长。所以更
- List item
适合在移动端使用
- 场景:类似抖音、小红书、淘宝展示信息的布局
11.CSS和CSS3有什么区别?
CSS3是在CSS的基础上新增了一些特性
CSS3新特性?
- CSS3圆角 border-radius:25px;
- CSS3盒阴影 box-shadow: 10px 10px 5px #888;
- CSS3边框图片 border-image:url(border.png) 30 30 round
- CSS3背景 background: url(img_flwr.gif);
- CSS3渐变 background-image: linear-gradient(#e66465, #9198e5);
- CSS3文本效果 text-shadow: 5px 5px 5px #FF0000;
- CSS3字体 font-family: myFirstFont;
- CSS2D转换 transform: translate(x,y);
- CSS3D转换 transform-style: preserve-3d;
- CSS3过渡 transition:width 2s;
- CSS3动画
- CSS3多列 columns:100px 3;
- CSS3盒子模型 box-sizing:border-box;
- CSS3弹性盒子 display: flex;
- CSS3多媒体查询
@media screen and (min-width: 480px) {
body {
background-color: lightgreen;
}
}
12.什么是Flex布局?
为什么要使用Flex布局?
Flex布局是目前比较流行的一种布局,因为它十分简单灵活,区区简单几行代码就可以实现各种页面的的布局,以前我在学习页面布局的时候我深受其 float、display、position 这些属性的困扰。使用Flex属性就可以写出简洁优雅复杂的页面布局
目前整理了一些Flex布局常用的一些属性,以下简单说一下容器和项目的意思
- 容器:采用 Flex 布局的元素,称为容器
- 项目:指的是容器里面的子元素
容器的6个属性
- flex-direction:属性决定主轴的方向(即项目的排列方向)
- flex-wrap:默认情况下项目都排在一条轴线上,如果一行放不下如何处理(换行方式)
- flex-flow:flex-direction | flex-wrap(2个属性的简写)
- justify-content:项目在主轴上的对齐方式(默认水平对齐方式)
- align-items:项目在交叉轴上如何对齐(默认垂直对齐方式)
- align-content:多根轴线的对齐方式(即多行的对齐方式)
项目的6个属性
- order:项目的排列顺序。数值越小,排列越靠前,默认为0
- flex-grow:项目的放大(默认指宽度)比例,默认为0,即如果存在剩余空间,也不放大
- flex-shrink:项目的缩小(默认指宽度)比例,默认为1,即如果空间不足,该项目将缩小
- flex-basis:项目将占据固定空间(默认设置固定宽度)
- flex:flex-grow | flex-shrink | flex-basis(3个属性的缩写)
- align-self:允许单个项目有与其他项目不一样的对齐方式,可覆align-items属性
13.谈谈你对CSS选择器以及优先级的理解?
常用的CSS选择器
ID选择器、类选择器、标签选择器、属性选择器、伪类选择器、后代选择器
权重划分
在同一层级下
!important > 内联样式 > ID选择器 > 类选择器 > (标签选择器、伪类选择器、属性选择器)
不同层级下
正常来说权重值越高的优先级越高,但是一直以来没有具体的权重值划分,所以目前大多数开发中层级越深的优先级越高
14.浏览器的最小字号为12px,有哪些方式可以实现更小字号?
- 使用图片
- 使用字体文件
- 使用Canvas等绘图
- 使用CSS3 transform: scale(0.9) (目前来说比较方便的一种)
15.谈谈你对回流和重绘的理解?
什么是回流?
当一个元素自身的宽高,布局,显示或隐藏,或元素内部的文字结构发生变化,导致需要重新构建页面的时候,就产生了回流
什么是重绘?
当一个元素自身的宽高,布局,及显示或隐藏没有改变,而只是改变了元素的外观风格的时候,就产生了重绘
什么时候会进行回流?
- 添加或者删除可见的DOM元素的时候
- 元素的位置发生改变
- 元素的尺寸发生改变
- 内容改变
- 页面第一次渲染的时候
列举一些相关的CSS样式:width、height、line-height、padding、margin、diaplay、border、top、position、float、font-size、overflow等
什么时候会进行重绘?
列举一些相关的CSS样式:color、background、background-size、visibility、box-shadow
如何进行性能优化?
- 用transform 代替 top,left ,margin-top, margin-left… 这些位移属性
- 不要使用 js 代码对dom 元素设置多条样式,选择用一个 className 代替之
- 不要在循环内获取dom 的样式例如:offsetWidth, offsetHeight, clientWidth,
clientHeight等。浏览器有一个回流的缓冲机制,获取这些属性时会产生回流 - 避免设置多层内联样式,写个外部类这样只回流一次
- 让多次回流的元素脱离文档流比如动画,使用 position 属性的 fixed 值或 absolute 值
- 一起变化(同时修改所有需要变化的属性)
16.如何通过CSS绘制一个三角形?
width: 100px;
height: 100px;
border: 50px solid;
border-color: green transparent transparent transparent;
box-sizing: border-box;
17.CSS3动画能实现哪些过渡效果?
常用的动画分为2D和3D
2D:位移、旋转、放大缩小、渐变显示隐藏、变形
3D:旋转、视角放大缩小等
18.opacity: 0、visibility: hidden、display: none有什么区别?
以上几个属性都是属于隐藏元素,使用户看不见该元素。那么他们有什么区别呢?
19.让一个div水平垂直居中有几种方式?
方式1(利用margin和绝对定位)
方式2(利用flex布局)
20.请描述一下BFC、IFC、GFC 和 FFC的区别?
BFC(Block formatting contexts):块级格式上下文
页面上的一个隔离的渲染区域,那么他是如何产生的呢?可以触发BFC的元素有float、position、overflow、display:table-cell/ inline-block/table-caption ;BFC有什么作用呢?比如说实现多栏布局
IFC(Inline formatting contexts):内联格式上下文
IFC的line box(线框)高度由其包含行内元素中最高的实际高度计算而来(不受到竖直方向的padding/margin影响)IFC中的line box一般左右都贴紧整个IFC,但是会因为float元素而扰乱。float元素会位于IFC与与line box之间,使得line box宽度缩短。 同个ifc下的多个line box高度会不同
IFC中时不可能有块级元素的,当插入块级元素时(如p中插入div)会产生两个匿名块与div分隔开,即产生两个IFC,每个IFC对外表现为块级元素,与div垂直排列。
那么IFC一般有什么用呢?
水平居中:当一个块要在环境中水平居中时,设置其为inline-block则会在外层产生IFC,通过text-align则可以使其水平居中。
垂直居中:创建一个IFC,用其中一个元素撑开父元素的高度,然后设置其vertical-align:middle,其他行内元素则可以在此父元素下垂直居中
GFC(GrideLayout formatting contexts):网格布局格式化上下文
当为一个元素设置display值为grid的时候,此元素将会获得一个独立的渲染区域,我们可以通过在网格容器(grid container)上定义网格定义行(grid definition rows)和网格定义列(grid definition columns)属性各在网格项目(grid item)上定义网格行(grid row)和网格列(grid columns)为每一个网格项目(grid item)定义位置和空间。那么GFC有什么用呢,和table又有什么区别呢?首先同样是一个二维的表格,但GridLayout会有更加丰富的属性来控制行列,控制对齐以及更为精细的渲染语义和控制
FFC(Flex formatting contexts):自适应格式上下文
display值为flex或者inline-flex的元素将会生成自适应容器(flex container),可惜这个牛逼的属性只有谷歌和火狐支持,不过在移动端也足够了,至少safari和chrome还是OK的,毕竟这俩在移动端才是王道。Flex Box 由伸缩容器和伸缩项目组成。通过设置元素的 display 属性为 flex 或 inline-flex 可以得到一个伸缩容器。设置为 flex 的容器被渲染为一个块级元素,而设置为 inline-flex 的容器则渲染为一个行内元素。伸缩容器中的每一个子元素都是一个伸缩项目。伸缩项目可以是任意数量的。伸缩容器外和伸缩项目内的一切元素都不受影响。简单地说,Flexbox 定义了伸缩容器内伸缩项目该如何布局
21.如何理解冒泡排序?
什么是冒泡排序?
基本思想:冒泡排序,类似于水中冒泡,较大的数沉下去,较小的数慢慢浮起来
直观表达:即在数组排序中,从小到大排序
算法描述
从第一个数开始,每2个相邻的数进行比较,小的放在左边,大的放在右边。反反复复重复n遍,n即代表数组的长度 - 1
描述太多也没用,直接看图就能懂了
22.什么是原型、原型链、继承?
什么是原型?
每个函数都有prototype(原型)属性,这个属性是一个指针,指向一个对象,这个对象的用途是包含特定类型的所有实例共享的属性和方法,这个对象(原型对象)是用来给实例共享属性和方法的。
function Person() {}
Person.prototype.name = 'Nicholas';
Person.prototype.age = '29';
Person.prototype.job = 'SoftWare Engineer';
Person.prototype.sayName = function() {
console.log(this.name);
};
var person1 = new Person();
person1.sayName(); // Nicholas
var person2 = new Person();
person1.sayName(); // Nicholas
console.log(person1.sayName === person2.sayName); // true
以下是关系图
由上图可知
- 构造函数的prototype(原型)属性,指向原型对象
- 因为目前原型对象是属于Person构造函数的,所以它的constructor指向Person构造函数
- 实例1、实例2都是指向原型对象,所以就证明了Person.prototype定义的属性和方法都会共享给它的实例。即代码中person1.sayName
=== person2.sayName 返回true。即它们使用的确实是同一个函数(函数的引用地址相同) - 当调用构造函数创建一个新的实例后,该实例内部将包含一个指针(内部属性)即[[Prototype]],指向构造函数的原型对象。虽然在脚本中没有标准的方式访问[[Prototype]],但Firefox、Safari、Chrome等浏览器在每个对象上都支持一个属性_proto_;
- 要注意一点,实例1、实例2的[[Prototype]]都是指向原型对象,而不是直接指向构造函数本身
- 虽然无法访问[[Prototype]]属性,但是可以通过原型对象的isPrototypeOf()方法来判断实例是否指向该构造函数的原型对象,Person.prototype.isPrototypeOf(person1)
返回 true - 在ES5中,新增了一个方法 Object.getPrototypeOf(),返回[[Prototype]]的值
到目前为止,应该理解原型、原型对象、构造函数之间的关系了吧
什么是原型链?
假设一个原型对象等于另一个类型的实例,另一个类型的原型对象又等于另一个类型的实例。就像这样一层层递进,就构成了实例与原型的链条,这个就是所谓的原型链的基本概念
// 定义构造函数:超类
function SuperType() {
this.property = true;
}
SuperType.prototype.getSuperValue = function() {
return this.property;
};
// 定义构造函数:子类
function SubType() {
this.subproperty = false;
}
// SubType.prototype 等于 SuperType的实例,即重写SubType原型对象
SubType.prototype = new SuperType();
// 原型对象重写后又新增了方法
SubType.prototype.getSubValue = function() {
return this.subproperty;
};
var instance = new SubType();
关系图
什么是继承?
可以理解为,假设有函数A和函数B。函数A继承了函数B。那么函数B中的属性方法在函数A中也能访问和使用
继承的方式有很多:原型链继承、组合继承、原型式继承、寄生式继承、寄生组合式继承
23.谈谈你对this指向的了解?
this的指向不是在创建时就决定了,而是由执行环境决定的,包括全局环境、对象环境、构造函数环境、事件对象
全局环境
全局环境下,this就代表window对象
var name = 'xiaoming';
function say(){
console.log(this.name);
}
say(); //xiaomig
对象环境
对象环境指向对象
var obj = {
name : "xiaoming",
say : function(){
console.log(this.name);
}
}
obj.say(); //xiaoming
构造函数环境
构造函数中的this 会指向创建出来的实例对象
function Person() {
this.name = 'xiaoming';
}
var p = new Person();
console.log(p.name); // xiaoming
事件对象
在 DOM 事件中使用 this,this 指向了触发事件的 DOM 元素本身
li.onclick = function(){
console.log(this.innerHTML);
}
改变this指向的方法有哪些?
通过call()、apply()、bind()改变this指向
那么箭头函数中的this呢?
箭头函数体内的this对象,就是定义该函数时所在的作用域指向的对象,而不是使用时所在的作用域指向的对象
- 箭头函数本身没有this指向,如果使用this则指向上一级函数(非箭头函数)的this
- 箭头函数声明的构造函数不能够被new实例化
var name = 'window';
var A = {
name: 'A',
sayHello: () => {
console.log(this.name)
}
}
A.sayHello();// 还是以为输出A ? 错啦,其实输出的是window
这里的箭头函数,也就是sayHello,所在的作用域其实是最外层的js环境,因为没有其他函数包裹;然后最外层的js环境指向的对象是winodw对象,所以这里的this指向的是window对象
24.apply、call和bind是什么?哪些区别?
三者都是改变this指向的api
用法
apply:xxx.apply(this, [arg1, arg2])
call:xxx.call(this, arg1, arg2)
bind:xxx.bind(this, arg1, arg2)
区别
主要是传参方式和执行方式不同
- apply、call的区别:接受参数的方式不一样
- bind:不立即执行。而apply、call 立即执行
栗子
初始状态
let Person = function(name, age) {
this.name = name;
this.age = age;
};
let Student = function() {
this.class = 'classA';
this.run = function() {
console.log(this);
};
};
let student = new Student();
student.run();
使用apply改变this指向
let Person = function(name, age) {
this.name = name;
this.age = age;
};
let Student = function() {
this.class = 'classA';
this.run = function() {
Person.apply(this, ['xiaoming', 20]);
console.log(this);
};
};
let student = new Student();
student.run();
使用call改变this指向
let Person = function(name, age) {
this.name = name;
this.age = age;
};
let Student = function() {
this.class = 'classA';
this.run = function() {
Person.call(this, 'xiaoming', 20);
console.log(this);
};
};
let student = new Student();
student.run();
使用bind改变this指向
let ex = '';
let Person = function(name, age) {
this.name = name;
this.age = age;
};
let Student = function() {
this.class = 'classA';
this.run = function() {
ex = Person.bind(this, 'xiaoming', 20);
console.log(this);
};
};
let student = new Student();
student.run();
ex();
使用bind的话,需要执行了this改变才会生效
25.JS数据类型有哪些?
数据类型
- 基本类型 String、Number、Boolean、Null、Undefined
- 引用类型 Object、Array、Function
判断数据类型的方式
1. 使用typeof
typeof 'test' // string
typeof 1880 // number
typeof true // boolean
typeof null // object
typeof undefined // undefined
typeof {} // object
typeof [] // object
typeof function() {} // function
缺点:判断基本类型还是可以的,判断引用类型作用就没那么大了。无法校验数组、对象、Null
2. 使用constructor
let xiaoming = 'text';
xiaoming.constructor // String(){}
let xiaoming = 1880;
xiaoming.constructor // Number(){}
let xiaoming = true;
xiaoming.constructor // Boolean(){}
let xiaoming = null;
xiaoming.constructor // 报错
let xiaoming = undefined;
xiaoming.constructor // 报错
let xiaoming = {};
xiaoming.constructor // Object(){}
let xiaoming = [];
xiaoming.constructor // Array(){}
let xiaoming = function() {};
xiaoming.constructor // Function(){}
缺点:无法校验Null和Undefined
3. 使用instanceof
function A() {}
function A1() {}
function B() {}
A1.prototype = new A(); // A1 继承 A
let xiaoming = new A1(); // 实例化
console.log(xiaoming instanceof A); // true
console.log(xiaoming instanceof A1); // true
console.log(xiaoming instanceof B); // false