前端面试题(每天10个)

6 篇文章 1 订阅

说不定哪天就要重新找工作了,作为知识的储备和巩固学习,每天记一点东西总归是好的。(尽可能的每天更新一点)

目录

HTML

Doctype 有什么用?

HTML 中用来区分标准模式和怪异模式的声明,用来告知浏览器使用标准模式渲染页面。

什么是 data- 属性?

在 JavaScript 框架流行之前,前端开发者经常使用 data- 属性,把额外的数据存储在 DOM 自身中。当时没有其他的 Hack 手段(比如使用非标准属性或 DOM 上额外属性)。这样做是为了将自定义数据存储到页面或应用中,对此没有其他更适当的属性或元素。
而现在,不鼓励使用 data- 属性。原因之一数据模型可以存储在 JavaScript 本身中,并利用框架提供的数据绑定,使之与 DOM 保持更新。

请描述 script、 script async 和 script defer 的区别
  • <script>:浏览器会立即加载并执行相应的脚本。也就是说在渲染script标签之后的文档之前,不等待后续加载的文档元素,读到就开始加载和执行,此举会阻塞后续文档的加载。
  • <script async>:表示后续文档的加载和渲染与js脚本的加载和执行是并行进行的,即异步执行。
  • <script defer>:加载后续文档的过程和js脚本的加载(此时仅加载不执行)是并行进行的(异步),js脚本的执行需要等到文档所有元素解析完成之后,DOMContentLoaded事件触发执行之前。如果存在多个有defer属性的脚本,那么它们是按照加载顺序执行脚本的。
什么是渐进式渲染(progressive rendering)?

渐进式渲染适用于提高网页性能,以尽快呈现页面的额技术。例如:

  • 图片懒加载—页面上图片不会一次性全部加载,当用户滚动页面到图像部分时,JavaScript 将加载冰心啊是图像。
  • 分层次渲染(确认显示内容的优先级)—为了尽快将页面呈现给用户,页面只包含基本的最少量的 css、脚本和内容,可以使用延迟加载脚本或者监听 DOMContentLoaded/load 事件加载其他资源和内容。
  • 异步加载 HTML 片段—当页面通过后台渲染时,把 HTML 拆分,通过异步请求,分块发送给浏览器。
HTML5 的新特性,语义化

HTML5 中诞生了一些特殊的标签,见名知意,使页面更清晰,方便维护和开发。

  1. <section></section>:定义文档中的主体部分的节、段。
  2. <article></article>:定义来自外部的一个独立的、完整的内容块,例如什么论坛的文章,博客的文本。
  3. <aside></aside>:用来装载页面中非正文的内容,独立于其他模块。例如广告、成组的链接、侧边栏。
  4. <header></header>:定义文档、页面的页眉。
  5. <footer></footer>:定义了文档、页面的页脚。
  6. <nav></nav>:定义了一个链接组组成的导航部分。
  7. <hgroup></hgroup>:用于对网页或区段(section)的标题元素(h1~h6)进行组合。
  8. <figure></figure>:用于对元素进行组合。
  9. <canvas></canvas>:用来进行canvas绘图。
  10. <video></video>:定义视频。
  11. <audio></audio>:定义音频。
meta 标签

<meta> 标签提供关于 HTML 文档的元数据。可用于浏览器(如何显示内容或重新加载页面),搜索引擎(关键词),或其他 web 服务。
<meta> 标签的属性有四个:namehttp-equivcontentcharset






CSS

盒模型,box-sizing
  • 盒模型:当设置元素的大小时,width 和 height 属性确定元素的内容框的宽度和高度。添加到元素上任意的 padding 都将增加元素的总计算宽度和(或)高度 —— 这是默认的盒模型在调整元素大小时的工作原理。
  • box-sizing:使用 box-sizing 属性,你可以告诉浏览器在元素的宽度中包括 padding 的宽度和(或) border 宽度,而不是增加该宽度。
伪类,伪元素
  • 伪类:用于向某些选择器添加特殊的效果
  • 伪元素:用于向某些选择器设置特殊效果

伪类

属性描述css版本
:active向被激活的元素添加样式1
:focus向拥有键盘输入焦点的元素添加样式2
:hover当鼠标悬浮在元素上方时,想元素添加样式1
:link向未被访问的链接添加样式1
:visited向已被访问的链接添加样式1
:first-child向元素的第一个子元素2
:lang向带有指定 lang 属性的元素添加样式2

提示:在 CSS 定义中,a:hover 必须被置于 a:link 和 a:visited 之后,才是有效的。
提示:在 CSS 定义中,a:active 必须被置于 a:hover 之后,才是有效的。
提示:伪类名称对大小写不敏感。

伪元素

属性描述css版本
:first-letter向文本的第一个字母添加特殊样式1
:first-line想文本首行添加特殊样式1
:before在元素之前添加内容2
:after在元素之后添加内容2
CSS实现隐藏页面的方式

你可以将 opacity 设为 0、将 visibility 设为 hidden、将 display 设为 none 或者将 position 设为 absolute 然后将位置设到不可见区域。

css属性是否区分大小写?

不区分。HTML 、CSS 都对大小写不敏感,但为了更好的可读性和团队协作一般都小写,而在 XHTML 中元素名称和属性必须小写

行内(inline)元素,设置 margin-top 和 margin-bottom 是否起作用?

答案是起作用,个人觉得不对。
讨论这个问题,应该对行内替换元素和行内非替换元素分别讨论。对于行内非替换元素,是不起作用的,原因在于行内非替换元素的外边距不会改变一个元素的行高,但是对其左右边距则不是这样的,是有影响的。而对于替换元素则是都有影响的。

对内联元素设置 padding-top 和 padding-bottom 是否会增加它的高度?

答案是不会

设置 p 的 font-size:10rem,当用户重置或拖曳浏览器窗口时,文本大小是否会随着变化?

不会。 rem 是以 html 根元素中的 font-size 的大小为基准的相对度量单位,文本大小不会对窗口大小改变而变化。

伪类选择器:checked 将作用在与 input 类型为 radio 或者 checkbox ,不会作用于 option

不对。

在 HTML 文本中,伪类:root 总是指向html元素?

不是。单创建的根。这个可能不是html。

translate()方法能移动一个元素在 z 轴上的位置?

不能,该方法只能改变 x 轴,y 轴上的位移。

only选择器的作用是?

停止旧版本浏览器解析选择器的其余部分。

overflow:hidden 是否形成新的块级格式化上下文?

会触发 BFC 的条件有:

  • float 值不为 none。
  • overflow 的值不为 visible。
  • display 的值为 table-cell、table-caption、inline-block 中的任何一个。
  • positon 的值不为 relative 和 static。
screen 关键词是指设备物理屏幕的大小还是指浏览器的视窗?

浏览器视窗。

浮动元素引起的问题和解决办法?
  1. 在浮动元素的最后加一个兄弟元素设置css样式:{ clear:both }
  2. 使用父元素的伪类元素 ::after,设置样式:{ clear:both }






JavaScript

window.onload和document.ready的区别
window.onload是在页面中包含图片在内的素有元素全部加载完成;
document.ready是文档结构加载完成,但不包含图片,其他媒体文件;
在jQuery中会看到$(function(){})和$(document).ready(function(){}),是在DOM树加载完成之后执行;
window.onload是在DOM树加载完以及所有文件加载完成才执行,因此慢于document.ready。
数组去重
var arr = ['a','bb','22','a','yuci','haha','22']; 

# es6的set()方法

var unique = new Set(arr);  
console.log(Array.from(unique)); 

#使用push()

var arr2 = [];  
for(var i = 0; i < arr.length; i++) {  
    (function(i) {  
        if(arr2.indexOf(arr[i]) == -1) { //不包含某个值则返回-1  
            arr2.push(arr[i]);  
        }  
    }(i))  
}  
console.log(arr2); 
//如果当前数组的第i项在当前数组中第一次出现的位置不是i,那么表示第i项是重复的,忽略掉。否则存入结果数组  
var arr3 = [arr[0]];  
for(var i = 1; i < arr.length; i++) {  
    (function(i) {  
        if(arr.indexOf(arr[i]) == i) {  
            arr3.push(arr[i]);  
        }  
    }(i))  
}  
console.log(arr3);  

#排序去除相邻重复元素

var arrSort = arr.sort();  
var arr4 = [];  
for(let i = 0; i< arrSort.length; i++) {  
    if(arrSort[i] != arrSort[i+1]) {  
        arr4.push(arrSort[i]);  
    }  
}  
console.log(arr4);  

#使用splice()

var len = arr.length;  
for(let i = 0; i < len; i++) {  
    for(let j = i + 1; j < len; j++) {  
        if(arr[i] === arr[j]) {  
            arr.splice(i,1);  
            len--;  
            j--;  
        }  
    }  
}  
console.log(arr); 
事件委托

得益于事件冒泡,当多个元素有相同的事件,将事件绑定在父元素

var oUl = document.getElementById('oul');  
oUl.addEventListener('click', function(e) {  
    var e = e||window.event;  
    var tar = e.target;  
    if(tar.nodeName === 'LI') {  
        alert(tar.innerHTML);  
    }  
}) 
判断变量类型

typeof()用于判断简单数据;

判断一个变量是对象还是数组使用instanceof,constructor或Object.prototype.toString.call();
同步和异步

同步:由于js单线程,同步任务都在主线程上排队执行,前面任务没执行完成,后面的任务会一直等待;
异步:不进入主线程,进入任务队列,等待主线程任务执行完成,开始执行。最基础的异步操作setTimeout和setInterval,等待主线程任务执行完,在开始执行里面的函数;

返回false的几种情况

false,null,0,“”,undefined,NaN

js类型值的区别
**存储地**:

简单数据类型:存储在栈中;

引用数据类型:存储在堆中,在栈中存储了指针,指向存储在堆中的地址,解释器会先检索在栈中的地址,从堆中获得实体;

**大小**:

简单数据类型:大小固定,占用空间小,频繁使用,所以存储在栈中;

引用数据类型:大小不固定,占用空间大;
闭包

何为闭包:有权访问另一个作用域中变量的函数
闭包特性:可实现函数外访问函数内变量,外层变量可以不被垃圾回收机制回收

为什么?怎么解决?

for(var i = 0; i < 10; i++) {  
    setTimeout(function() {  
        console.log(i);    
    }, 1000);  
}
// 使用闭包,自执行匿名函数包裹:
for(var i = 0; i < 10; i++) {  
    (function(j) {  
        setTimeout(function() {  
            console.log(j);    
        }, 1000);  
    })(i);  
} 
this的指向
全局范围:指向window(严格模式下不存在全局变量,指向undefined);

普通函数调用:指向window;

对象方法调用:指向最后调用它的对象;

构造函数调用:指向new出来的对象;

显示设置this:call,apply方法显示将this指向第一个参数指明的对象
new具体做了些什么
创建一个新对象foo;

并将它的__proto__指向其构造函数的prototype,foo.__proto__ = Foo.prototype;

动态将this指向新对象,Foo.apply(foo,arguments);

执行函数体中的代码;

放回新对象foo;
原型和原型链

创建一个函数就会为其创建一个prototype属性,指向这个函数的原型对象,原型对象会自动获得constructor属性,指向prototype属性所在函数。

Function.prototype.a = "a";    
Object.prototype.b = "b";    
function Person(){}    
console.log(Person);    //function Person()    
let p = new Person();    
console.log(p);         //Person {} 对象    
console.log(p.a);       //undefined    
console.log(p.b);       //b 

p.__proto__ === Person.prototype;Person.prototype.constructor === Person

当调用某种方法或查找某种属性时,首先会在自身调用和查找,如果自身并没有该属性或方法,则会去它的proto属性中调用查找,也就是它构造函数的prototype中调用查找,如果构造函数中也没有该属性方法,则会去构造函数的隐式原型中查找,一直到null,就这样形成原型链。

数组常用方法
  • 尾部删除pop()
  • 尾部添加push()
  • 头部删除shift()
  • 头部添加unshift()
  • 排序sort()
  • 颠倒数组元素reverse()
  • 删除或插入元素splice()
数据存储
方法名称属性大小失效时间
Cookie用于客户端与服务端通信,也具有本地存储的功能4K在浏览器关闭时删除,除非主动设置删除时间
localStorage专门用于存储5M一直都在直到用户主动删除或清除浏览器缓存
sessionStorage专门用于存储5M浏览器关闭时删除
继承方式

原型链继承:
Child()的原型作为Parent()的实例来继承Parent()的方法属性
因为所有实例都继承原型方法属性,其中一个实例对原型属性值更改后,所有实例调用该属性的值全部更改

function Parent() {}  
Parent.prototype.parentSay = function() {  
    return 'i am parent';  
}  
function Child() {}  
Child.prototype.childSay = function() {  
    return 'i am child';  
}  
Child.prototype = new Parent();  
var par = new Parent();  
var kid = new Child();  

console.log(kid.parentSay());           //i am parent 

构造函数继承:
在子类的构造函数内部通过callapply来调用父类构造函数
无法实现函数的复用

function People() {  
    this.name = ['zhangsan','lisi','wangwu'];  
}  
function Person() {  
    People.call(this);  
}  
var per1 = new Person();  
per1.name.push('zhanliu');  
console.log(per1.name);     //["zhangsan", "lisi", "wangwu", "zhanliu"]  

var per2 = new Person();  
console.log(per2.name);     //["zhangsan", "lisi", "wangwu"]  

组合继承:
将原型链继承和构造函数继承结合,最常用的继承模式
原型链继承共享的属性和方法,构造函数继承实例属性

function People(num) {  
    this.num = num;  
    this.name = ['zhangsan','lisi','wangwu'];  
}  
People.prototype.numCount = function() {  
    console.log(this.num);  
}  
function Person(num) {  
    People.call(this, num);  
}  
//继承方式  
Person.prototype = new People();  
Person.prototype.constructor = Person;  

var per1 = new Person(10);  
per1.name.push('zhaoliu');  
console.log(per1.name);     //["zhangsan", "lisi", "wangwu", "zhanliu"]  
per1.numCount();            //10  

var per2 = new Person(20);  
console.log(per2.name);     //["zhangsan", "lisi", "wangwu"]  
per2.numCount();            //20  






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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值