前端面试十

46、在做项目的时候有用到哪些基础知识或者说技术栈

面向对象、继承、ajax通信原理、跨域问题、性能优化、公用模块的提取、制作图标icon、代码优化等

1)整个项目使用jquery框架搭建,jquery是js的一个库,他封装了js对象以及事件,从而极大的简化了js的编程,对于操作DOM更加方便

2)首页的轮播图采用bootstrap.js制作

3)对于一些弹窗提示,则把Bootstrap中提供的弹窗进行封装成.html文件,方便多处引用

4)对于请求回来的时候会有一个弹窗提示,这个弹窗采用toastr.js插件实现

5)首页大屏幕的背景图可以设置,背景图的样式有提供一些默认的样式进行选择以及自定义上传背景图,在背景图样式展示的时候,采用masterSlider.js插件实现对样式图片的展示,使用懒加载技术

6)同时由于该页面有多张图片,那么需要一个懒加载技术进行处理,从而提高访问页面的速度

7)在大屏幕的互动环节中有“超级弹幕”、“霸屏”、“赛车”功能,在移动端都提供了显示的样式的选择,对于样式的显示的话,采用swiper.js进行处理

8)在大屏主页下,可以通过微信发消息上墙,消息的滚动效果采用了velocity.js插件进行优化

8)由于浏览器缓存的问题,浏览器显示的内容不是最新更改之后的内容,那么这时候需要给文件添加版本号,从而解决浏览器缓存的问题

9)客户端和服务器端的通信采用jquery封装的ajax()方法

10)由于ajax通信存在跨域问题,那么在项目中的解决方法是采用CORS(跨域资源共享)的方法解决,即在服务端设置http的header头,包括access-control-allow-origin:*(服务端这边允许任何域的访问)、acce-control-allow-methods等

11)由于有些模块是公用的,比如导航栏、提示框、qq客服等公用模块,在项目中将他们封装成独立的.htm模块

12)对于性能优化的话,有从加载优化、css、js、image优化、渲染优化

 

 

1)模块化的思想:比如请求成功与失败的提示框,将其html和css分别写在一个文件里面,等到需要的地方的时候,在将其引进来

2)ajax通信原理:ajax通信的原理,以及ajax存在的安全性问题以及如何解决这些安全性问题等

3)由于浏览器同源策略的限制,ajax请求存在跨域请求的问题:什么样的情况下会造成跨域问题?解决跨域有哪些解决方法?

4)继承:实现继承的方法有哪些,现场编写一个实现继承的方法

5)原型链,原型继承

6)性能优化的方法

 

48、什么叫优雅降级和渐进增强

渐进增强 :针对低版本浏览器进行构建页面,保证最基本的功能,然后再针对高级浏览器,进行效果、交互改进追加功能达到更好的用户体验。

优雅降级 :一开始就构建完整的功能,然后再针对低版本浏览器进行兼容

49、HTTP和HTTPS的区别

HTTP协议通常承载于TCP协议之上,在HTTP和TCP之间添加一个安全协议层(SSL或TSL),这个时候,就成了我们常说的HTTPS。默认的HTTP的端口号为80,HTTPS的端口号为443

50、为什么说HTTPS是安全的网络协议

因为网络请求中间需要有有很多的服务器、路由器的转发。中间的节点都可能篡改信息,而如果使用HTTPS,密钥在你和终点站才有。https之所以比http安全,是因为他利用ssl/tsl协议传输,它包含证书,卸载,流量转发,负载均衡,页面适配,浏览器适配,refer传递等,保障了传输过程的安全性

 

51、javascript垃圾回收方法

标记清除(mark and sweep)

这是JavaScript最常见的垃圾回收方式,当变量进入执行环境的时候,比如函数中声明一个变量,垃圾回收器将其标记为“进入环境”,当变量离开环境的时候(函数执行结束)将其标记为“离开环境”。
垃圾回收器会在运行的时候给存储在内存中的所有变量加上标记,然后去掉环境中的变量以及被环境中变量所引用的变量(闭包),在这些完成之后仍存在标记的就是要删除的变量了。

引用计数(reference counting)

在低版本IE中经常会出现内存泄露,很多时候就是因为其采用引用计数方式进行垃圾回收。引用计数的策略是跟踪记录每个值被使用的次数,当声明了一个 变量并将一个引用类型赋值给该变量的时候这个值的引用次数就加1,如果该变量的值变成了另外一个,则这个值得引用次数减1,当这个值的引用次数变为0的时 候,说明没有变量在使用,这个值没法被访问了,因此可以将其占用的空间回收,这样垃圾回收器会在运行的时候清理掉引用次数为0的值占用的空间。
 

那些操作会造成内存泄漏

内存泄漏:就是变量占用的空间无法被垃圾回收器回收,同时又不能使用该空间,就称为内存泄漏

1)意外的全局变量引起的内存泄露---在函数内声明一个变量的时候漏掉var

function leak(){
  leak="xxx";//leak成为一个全局变量,不会被回收
}

减少全局变量的污染:使用命名空间,将变量封装起来;使用闭包封装私有变量,暴露一些接口跟外界通信

2)闭包引起的内存泄露----由于闭包可以访问函数内部定义的变量并使其一直保存在内存中不释放

 

3)没有清理的DOM元素引用

var elements={
    button: document.getElementById("button"),
    image: document.getElementById("image"),
    text: document.getElementById("text")
};
function doStuff(){
    image.src="http://some.url/image";
    button.click():
    console.log(text.innerHTML)
}
function removeButton(){
    document.body.removeChild(document.getElementById('button'))
}

4)被遗忘的定时器或者回调函数,即处理函数不会被回收

var someResouce=getData();
setInterval(function(){
    var node=document.getElementById('Node');
    if(node){
        node.innerHTML=JSON.stringify(someResouce)
    }

 

怎样避免内存泄露

1)减少不必要的全局变量,或者生命周期较长的对象,及时对无用的数据进行垃圾回收

2)注意程序逻辑,避免“死循环”之类的 

3)避免创建过多的对象  原则:不用了的东西要及时归还

 

 

 

54、栈和队列的区别

1)栈的插入和删除操作都是在一端进行的,而队列的操作却是在两端进行的

2)队列先进先出,栈先进后出

3)栈只允许在表尾一端进行插入和删除,而队列只允许在表尾一端进行插入,在表头一端进行删除

 

 

 

55、堆和栈的区别

堆(数据结构):堆可以被看成是一棵树,如:堆排序

栈(数据结构):一种先进后出的数据结构

堆区(heap)   —   一般由程序员分配释放,   若程序员不释放,程序结束时可能由OS回收

栈区(stack)—   由编译器自动分配释放   ,存放函数的参数值,局部变量的值等

 

5、JavaScript原型,原型链 ? 有什么特点?

1、js中每个函数都存在有一个原型对象属性prototype,并且所有函数的默认原型都是Object的实例

2、每个继承父函数的子函数的对象都包含一个内部属性_proto_,该属性包含一个指针,指向父函数的prototype。若父函数的原型对象_proto_属性为再上一层函数,在此过程中就形成了原型链
 

3、原型链实现了继承,原型链存在两个问题:a 包含引用类型值原型属性会被所有实例共享。b 在创建子类型时,无法向超类型的构造函数中传递参数

 

 

159、javascript中实现继承的方式

javascript 面向对象中继承实现方式

 

1)原型链继承的原理

原型链的末端是Object的原型对象,值为null

● JavaScript没有类的概念,也没有“”(class)和“实例”(instance)的区分,全靠“原型链”(prototype chain)模式,来实现继承

原理

构造函数、原型、实例的关系:

每个构造函数有一个原型对象,原型对象有一个指向构造函数的指针,实例都包含一个指向原型对象的内部指针

让构造函数的原型对象为另一个构造函数的实例对象,另一个构造函数的原型对象又是另一个另一个构造函数的实例对象,如此层层递进,就构成了实例与原型的链条。这就是原型链的概念

原型链继承的缺点:引用类型值的原型属性被所有实例共享;在创建子类型的实例的时候,无法给超类型传递参数

原型链继承的代码

function Supper(){
    this.property = true;
}

Supper.prototype.getSupperProperty=function(){
    return this.property;
}

function Subber(){
    this.SubberProperty = false;
}

Subber.prototype = new Supper();  //将另一个类的实例赋给另一个类的原型,从而实现继承

Subber.prototype.getSubberProperty=function(){
    return this.SubberProperty;
}

var temp = new Subber();
console.log(temp.getSupperProperty());

 

2)借用构造函数(经典继承、伪造对象)

原理:在子类型构造函数的内部调用超类型的构造函数。由于函数是在特定环境中执行代码的对象,所以通过使用apply()、call()、也可以在新创建的对象上执行构造函数

function SuperType(name){
	this.colors = ['red','green','blue'];
	this.name = name;
}

function SubType(name){
	//继承了SuperType
	// SuperType.apply(this);
	SuperType.call(this,name);
}

var instance1 = new SubType('jiang');
instance1.colors.push('black');
console.log(instance1.colors);
console.log(instance1.name);

var instance2 = new SubType('ke'); //SubType的每个实例都有自己的colors属性的副本
console.log(instance2.colors);
console.log(instance2.name);


3)组合继承:使用原型链实现对原型属性和方法的继承,通过借用构造函数来实现对实例属性的继承。这样通过在原型上定义方法实现函数复用,又能够保证每个实例都有自己的属性

function SuperType(name){
	this.colors = ['red','green','blue'];
	this.name = name;
}

SuperType.prototype.sayName = function(){
	console.log(this.name);
};

function SubType(name,age){
	//继承了超类型SuperType中的属性
	// SuperType.apply(this);
	SuperType.call(this,name);
	this.age = age;
}

//继承超类型中的原型方法
SubType.prototype = new SuperType();
SubType.prototype.constructor = SubType;
SubType.prototype.sayAge = function(){
	console.log(this.age);
};

var instance1 = new SubType('jiang',1);
instance1.colors.push('black');
console.log(instance1.colors);
instance1.sayName();
instance1.sayAge();

var instance2 = new SubType('ke',5);
console.log(instance2.colors);
instance1.sayName();
instance2.sayAge();

 

55、js继承方式及其优缺点

1)原型链继承的缺点:引用类型值的原型属性被所有实例共享;在创建子类型的实例的时候,无法给超类型传递参数

2)借用构造函数(经典继承,伪造对象):借用构造函数虽然解决了刚才两种问题,但没有原型,则复用无从谈起。所以我们需要原型链+借用构造函数的模式,这种模式称为组合继承

3)组合继承:使用原型链实现对原型属性和方法的继承,而通过借用构造函数来实现对实例属性的继承。这样,既通过在原型上定义方法实现了函数复用,又保证每个实例都有它自己的属性

4)原型式继承

5)寄生式继承

6)寄生组合式继承

 

 

57、谈谈浮动和清除浮动

浮动的框可以向左或向右移动,直到他的外边缘碰到包含框或另一个浮动框的边框为止。由于浮动框不在文档的普通流中,所以文档的普通流的块框表现得就像浮动框不存在一样。浮动的块框会漂浮在文档普通流的块框上

清除浮动的方法:

1)使用空标签清除浮动:这种方法是在所有浮动标签后面添加一个空标签,定义css clear:both. 弊端就是增加了无意义标签

2)使用overflow: 给包含浮动元素的父标签添加css属性 overflow:hidden; zoom:1为了兼容IE   缺点:超出父元素区间的内容会被隐藏起来

3)使用after伪元素清除浮动:该方法只适用于非IE浏览器。使用中需注意以下几点。一、该方法中必须为需要清除浮动元素的伪对象中设置 height:0,否则该元素会比实际高出若干像素  推荐使用这种方式

#parent:after{

        content:".";

        height:0;

        visibility:hidden;

        display:block;

        clear:both;
 }

4)使用双伪元素清除浮动: 是第三种的改进版,但是不严谨

           .clearfix:before,.clearfix:after {

                  content: "";

                  display: block;

                  clear: both;

            }

            .clearfix {

                  zoom: 1;

            }

浮动元素引起的问题:

1)父元素的高度无法被撑开,影响与父元素同级的元素(设置after伪类)

2)与浮动元素同级的非浮动元素(内联元素)会跟随其后 (clear:both)

3)若非第一个元素浮动,则该元素之前的元素也需要浮动,否则会影响页面显示的结构 (clear:both)

 

60、position:absolute和float属性的相同和不同点

共同点:对内联元素设置float和absolute属性,可以让元素脱离文档流,并且可以设置其宽高

区别:float仍会占据位置,absolute会覆盖文档流中的其他元素

 

62、CSS 选择符有哪些?哪些属性可以继承?优先级算法如何计算? CSS3新增伪类有那些?

 

CSS 选择符有哪些:

 1)id选择器( #myid)

 2)类选择器(.myclassname)

 3)标签选择器(div, h1, p)

 4)相邻选择器(h1 + p)

 5)子选择器(ul > li)

 6)后代选择器(li a)

 7)通配符选择器( * )

 8)属性选择器(a[rel = "external"])

 9)伪类选择器(a: hover, li:nth-child(1))

 

 

在CSS中哪些属性可以同父元素继承

一、无继承性的属性
1、display:规定元素应该生成的框的类型
2、文本属性
vertical-align:垂直文本对齐
text-decoration:规定添加到文本的装饰
text-shadow:文本阴影效果
white-space:空白符的处理
unicode-bidi:设置文本的方向
3、盒子模型的属性widthheightmargin 、margin-top、margin-right、margin-bottom、margin-left、borderborder-style、border-top-style、border-right-style、border-bottom-style、border-left-style、border-width、border-top-width、border-right-right、border-bottom-width、border-left-width、border-color、border-top-color、border-right-color、border-bottom-color、border-left-color、border-top、border-right、border-bottom、border-left、paddingpadding-top、padding-right、padding-bottom、padding-left
4、背景属性:background、background-color、background-image、background-repeat、background-position、background-attachment
5、定位属性:float、clear、position、top、right、bottom、left、min-width、min-height、max-width、max-height、overflow、clip、z-index
6、生成内容属性:content、counter-reset、counter-increment
7、轮廓样式属性:outline-style、outline-width、outline-color、outline
8、页面样式属性:size、page-break-before、page-break-after
9、声音样式属性:pause-before、pause-after、pause、cue-before、cue-after、cue、play-during


二、有继承性的属性
1、字体系列属性
font:组合字体
font-family:规定元素的字体系列
font-weight:设置字体的粗细
font-size:设置字体的尺寸
font-style:定义字体的风格
font-variant:设置小型大写字母的字体显示文本,这意味着所有的小写字母均会被转换为大写,但是所有使用小型大写字体的字母与其余文本相比,其字体尺寸更小
font-stretch:对当前的 font-family 进行伸缩变形。所有主流浏览器都不支持
font-size-adjust:为某个元素规定一个 aspect 值,这样就可以保持首选字体的 x-height。
2、文本系列属性
text-indent:文本缩进
text-align:文本水平对齐
line-height:行高
word-spacing:增加或减少单词间的空白(即字间隔)
letter-spacing:增加或减少字符间的空白(字符间距)
text-transform:控制文本大小写
direction:规定文本的书写方向
color:文本颜色
3、元素可见性:visibility
4、表格布局属性:caption-side、border-collapse、border-spacing、empty-cells、table-layout
5、列表布局属性:list-style-type、list-style-image、list-style-position、list-style
6、生成内容属性:quotes
7、光标属性:cursor
8、页面样式属性:page、page-break-inside、windows、orphans
9、声音样式属性:speak、speak-punctuation、speak-numeral、speak-header、speech-rate、volume、voice-family、pitch、pitch-range、stress、richness、、azimuth、elevation

三、所有元素可以继承的属性
1、元素可见性:visibility
2、光标属性:cursor

四、内联元素可以继承的属性
1、字体系列属性
2、除text-indent、text-align之外的文本系列属性

五、块级元素可以继承的属性
1、text-indent、text-align

 

div标签设置margin:0 auto会水平居中的原因?

margin:margin-top  margin-right  margin-bottom  margin- left,如果只设置两个值的话,那么就相当于margin-top和margin-bottom设置的值一样,margin-left和margin-right设置的值一样的,当设置margin:0 auto的时候就相当于margin-top=margin-bottom为0,而auto是自动调整大小,margin-left=margin-right,即左右边距相同,当div有设置一个固定的width,那么浏览器的解析器就会自动调整margin-left和margin-right的值一样,这样就会水平居中了

 

 

CSS权重指的是样式的优先级,有两条或多条样式作用于一个元素,权重高的那条样式对元素起作用,权重相同的,后写的样式会覆盖前面写的样式

 

优先级算法

!important(10000) >内联(1000)> id (100)> 类| 伪类| 属性选择 (10)> tag| 伪元素(1)> 通用选择器(*)、子选择器(>)、相邻选择器(+)、同胞选择器(~)(0)> 继承,注意important 比内联优先级高,但内联比 id 要高

组合属性也是看上面的规则的

1、仅一个选择器单词的时候#id高于.class;

2、div#test2比#test2多了一个单词,那么多一个单词的优先级高;

3、同样多一个单词,但其中一个有#id选择,则#test3要高于div .test3;

4、.body #test4高于body #test4,同样多层级时,.class高于tag;

5、html #test5与body #test5有同样的优先级,先写的会被覆盖;

6、#body #test6高于.html #test6;

7、html #body #test7高于.html .body #test7;

8、#html.html .body #test8与.html #body.body #test8同级

 

css3新增的伪类

    p:first-of-type 选择属于其父元素的首个 

元素的每个

元素。 p:last-of-type 选择属于其父元素的最后

元素的每个

元素。 p:only-of-type 选择属于其父元素唯一的

元素的每个

元素。 p:only-child 选择属于其父元素的唯一子元素的每个

元素。 p:nth-child(2) 选择属于其父元素的第二个子元素的每个

元素。 :enabled :disabled 控制表单控件的禁用状态。 :checked 单选框或复选框被选中。

 

63、css3有哪些新特性

在项目开发中我们经常使用的css3新特性有以下几种

1)css3选择器:

a)ul li:last-child   匹配父元素的最后一个子元素li
b)ul li:nth-child(n)  匹配父元素的第n个子元素li 
c)ul li:nth-last-child(n)  匹配父元素的倒数第n个子元素li

2)@Font-face特性:加载字体样式,加载服务器端的字体文件,让客户端显示客户端所没有安装的字体

 

@font-face {   
     font-family: BorderWeb;   
     src:url(BORDERW0.eot);   
 }   

 .border { font-size: 35px; color: black; font-family: "BorderWeb" }   
 

@media媒体查询

3)圆角:border-radius

border-radius: 15px;  

4)阴影:box-shadow   text-shadow

5)css3的渐变效果:gradient

background-image:-webkit-gradient(linear,0% 0%,100% 0%,from(#2A8BBE),to(#FE280E)); 

css3制作动画特效

6)transition:对象变换时的过渡效果

 transition-property 对象参与过渡的属性
 transition-duration 过渡的持续时间
 transition-timing-function 过渡的类型
 transition-delay 延迟过渡的时间

transition:border-color .5s ease-in .1s, background-color .5s ease-in .1s, color .5s ease-in .1s; 

7)transform 2D转换效果

主要包括 translate(水平移动)、rotate(旋转)、scale(伸缩)、skew(倾斜)

 

  
 

8)animation动画

  
 

 

64、对BFC规范的理解

对一个元素设置CSS,首先需要知道这个元素是block还是inline类型。而BFC就是用来格式化块级盒子,同样管理inline类型的盒子还有IFC,以及其他的FC。

FC的定义: Formatting Context:指页面中的一个渲染区域,并且拥有一套渲染规则,他决定了其子元素如何定位,以及与其他元素的相互关系和作用

BFC的定义:块级格式化上下文就是一个相对独立的布局环境,它内部元素的布局不受外面布局的影响。在同一个BFC中的两个毗邻的块级盒在垂直方向(和布局方向有关系)的margin会发生折叠。

BFC的生成:满足下列CSS声明之一的元素便会生成BFC

1)根元素
2)float的值为left   right
3)overflow的值不为visible,即为auto   scroll  hidden
4)display的值为inline-block、table-cell、table-caption
5)position的值为absolute或fixed

 

 

66、null和undefined的区别

1)null是一个表示”无”的对象,转为数值时为0;undefined是一个表示”无”的原始值,转为数值时为NaN

2)当声明的变量还未被初始化时,变量的默认值为undefined

3)null用来表示尚未存在的对象,常用来表示函数企图返回一个不存在的对象

4)undefined的典型用法是:

(a)变量被声明了,但没有赋值时,就等于undefined。
(b) 对象没有赋值的属性,该属性的值为undefined
(c)调用函数时,应该提供的参数没有提供,该参数等于undefined 
(d)函数没有返回值时,默认返回undefined

5)null的典型用法

(a) 作为函数的参数,表示该函数的参数不是对象
(b) 作为对象原型链的终点

 

 

68、哪些操作会造成内存泄漏

内存泄漏指一块被分配的内存既不能使用,又不能回收,直到浏览器进程结束

1)意外的全局变量引起的内存泄漏

function leak(){  
  leak="hello";//leak成为一个全局变量,不会被回收  
}  

2)闭包引起的内存泄露

 

function bindEvent(){  
  var obj=document.createElement("p");  
  obj.onclick = function(){  //闭包不释放对外部函数的局部变量的引用
      //Even if it's a empty function  
  }  
}  

3)没有清理的DOM元素引用

 

var elements={  
    button: document.getElementById("button"),  
    image: document.getElementById("image"),  
    text: document.getElementById("text")  
};  
function doStuff(){  
    image.src="http://some.url/image";  
    button.click():  
    console.log(text.innerHTML)  
}  
function removeButton(){  
    document.body.removeChild(document.getElementById('button'))  

4)被遗忘的回调或者定时器

 

var someResouce=getData();  
setInterval(function(){  
    var node=document.getElementById('Node');  
    if(node){  
        node.innerHTML=JSON.stringify(someResouce)  
    }  
},1000);  

70、javascript对象创建的方法

javascript如何创建一个对象,?{画出次对象的内存图}

1)工厂模式

2)构造函数模式

3)原型模式

4)组合使用构造函数模式和原型模式

5)动态原型模式

6)寄生构造函数模式

7)稳妥构造函数模式

代码实现:

1)工厂模式:抽象了创建具体对象的过程,用函数来封装以特定接口创建对象的细节。

缺点:工厂模式虽然解决了创建多个相似对象的问题,但是却没有解决对象识别的问题。

function createtPerson(name,age,job){
	var o = new Object();
	o.name = name;
	o.age = age;
	o.job = job;
	o.sayName = function(){
		console.log(this.name);
	};
	return o;
}

var person1 = createtPerson('ke',1,'teacher');
person1.sayName();

2)构造函数模式:可以用来创建特定类型的对象

缺点每个方法都要在每个实例上重新创建一遍,即不同实例上的同名函数是不相等的

构造函数在不返回值的时候,默认返回新对象实例

function Person(name,age,job){
	this.name = name;
	this.age = age;
	this.job = job;
	this.sayName = function(){
		console.log(this.name);
	};
}

var person1 = new Person('ke',1,'teacher');
person1.sayName();

3)原型模式:创建的每个函数都有一个prototype属性,它是一个指针,指向一个对象,这个对象的用途是包含可以由特定类型的所有实例共享的属性和方法,即可以将对象实例共享的属性和方法添加到原型对象上。

缺点:a)--省略了为构造函数传递初始化参数这一环节,所有实例在默认的情况下都将取得相同的属性值

         b)--原型中所有的属性都是被实例共享的,如果属性是引用类型的话,那么在某个实例上对该属性的 修改都会反映到所有的实例对象上

function Person(){

}
Person.prototype.name = 'ke';
Person.prototype.age = 1;
Person.prototype.job = 'teacher';
Person.prototype.sayName = function(){
	console.log(this.name);
};

var person1 = new Person();
var person2 = new Person();
person1.name = 'jiang';//只是覆盖原型上的同名属性,并不能修改原型上的值,彻底删除实例上的同名属性用delete,delete person1.name,这样就可以
person1.sayName();     //访问原型上的name的值了
person2.sayName();

 

4)组合使用构造函数模式和原型模式:构造函数模式定义实例属性,原型模式定义方法和共享的属性。

优点:a)--每个实例都有自己的一份实例属性的副本,但同时又共享着对方法的引用,最大限度的节省了内存

         b)--支持向构造函数传递参数

function Person(name,age,job){
	this.name = name;
	this.age = age;
	this.job = job;
	this.friends = ['ke','xiu'];
}

Person.prototype = {
	constructor:Person,
	sayName:function(){
		console.log(this.name);
	}
};

var person1 = new Person('hua',1,'teacher');
var person2 = new Person('jiang',2,'engineer');

person1.friends.push('qing');
console.log(person1.friends);
console.log(person2.friends);

5)动态原型模式:在组合使用构造函数模式和原型模式中,构造函数和原型是独立的,而动态原型模式则是把所有的信息都封装在构造函数中,在构造函数中初始化原型,即通过检查某个应该存在的方法是否有效,来决定是否需要初始化原型。对原型的修改能够立即反映在所有的实例上

function Person(name,age,job){
	this.name = name;
	this.age = age;
	this.job = job;
	//在sayName()方法不存在的时候,才会添加到原型上
	//这段代码只会在初次条用构造函数的时候调用
	if(typeof(this.sayName) != 'function'){
		Person.prototype.sayName = function(){
			console.log(this.name);
		};	
	}
}

Person.prototype = {
	constructor:Person,
	sayName:function(){
		console.log(this.name);
	}
};

var person1 = new Person('hua',1,'teacher');
var person2 = new Person('jiang',2,'engineer');

person1.sayName();
person2.sayName();

6)寄生构造函数模式

 

7)稳妥构造函数模式

 

 

71、解释一下javascript的同源策略

同源策略是客户端脚本(尤其是Javascript)的重要的安全度量标准。它最早出自Netscape Navigator2.0,其目的是防止某个文档或脚本从多个不同源装载。
这里的同源策略指的是:协议,域名,端口相同,同源策略是一种安全协议。

为什么要有同源策略?

我们举例说明:比如一个黑客程序,他利用Iframe把真正的银行登录页面嵌到他的页面上,当你使用真实的用户名,密码登录时,他的页面就可以通过Javascript读取到你的表单中input中的内容,这样用户名,密码就轻松到手了

 

71、谈谈对重构的理解

网站重构:在不改变外部行为的前提下,简化结构、添加可读性,而在网站前端保持一致的行为。也就是说是在不改变UI的情况下,对网站进行优化,在扩展的同时保持一致的UI。
对于传统的网站来说重构通常是:

1)表格(table)布局改为DIV+CSS

2)使网站前端兼容于现代浏览器(针对于不合规范的CSS、如对IE6有效的)

3)对于移动平台的优化

4)针对于SEO进行优化

5)深层次的网站重构应该考虑的方面:

减少代码间的耦合;让代码保持弹性;严格按规范编写代码;设计可扩展的API;代替旧有的框架、语言(如VB);增强用户体验;压缩JS、CSS、image等前端资源(通常是由服务器来解决);程序的性能优化(如数据读写);采用CDN来加速资源加载;对于JS DOM的优化;HTTP服务器的文件缓存

 

 

 

72、浏览器缓存问题

有的时候,在本地修改了内容,但是在浏览器调试的时候,内容还是之前没有修改的版本,一直狂按刷新,才显示修改之后的内容。

解决方法:在引用的文件的路径的末尾加上随机序列号。

72、IE缓存问题

问题:在IE浏览器下,如果请求的方法是GET,并且请求的URL不变,那么这个请求的结果就会被缓存。

解决的方法:可以通过实时改变请求的URL,只要URL改变,就不会被缓存,可以通过在URL末尾添加上随机的时间戳参数('t'= + new Date().getTime())或者随机数rand=+Math.random()

 

73、谈谈对前端架构师的理解

1)负责前端团队的管理及与其他团队的协调工作,提升团队成员能力和整体效率; 
2)带领团队完成研发工具及平台前端部分的设计、研发和维护; 
3)带领团队进行前端领域前沿技术研究及新技术调研,保证团队的技术领先 
4)负责前端开发规范制定、功能模块化设计、公共组件搭建等工作,并组织培训

 

73、git fetch和git pull的区别

1)git pull:相当于是从远程获取最新版本,并merge到本地

2)git fetch:相当于是从远程获取最新版本到本地,不会自动merge

 

73、attribute和property的区别

1)attribute是HTML标签上的特性,它的值只能够是字符串,是我们赋予某个事物的特质或对象

2)property是DOM中的属性,是JavaScript里的对象,是早已存在的不需要外界赋予的特质

创建

1)DOM对象初始化时会创建默认的基本property;
2)只有在HTML标签中定义的attribute才会被保存在property的attributes属性中;
3)attribute会初始化property中的同名属性,但自定义的attribute不会出现在property中;
4)attribute的值都是字符串;
数据绑定
1)attributes的数据会同步到property上,然而property的更改不会改变attribute;
2)对于value,class这样的属性/特性,数据绑定的方向是单向的,attribute->property;
3)对于id而言,数据绑定是双向的,attribute<=>property;
4)对于disabled而言,property上的disabled为false时,attribute上的disabled必定会并存在,此时数据绑定可以认为是双向的;
使用
1)可以使用DOM的setAttribute方法来同时更改attribute;
2)直接访问attributes上的值会得到一个Attr对象,而通过getAttribute方法访问则会直接得到attribute的值;
3)大多数情况(除非有浏览器兼容性问题),jQuery.attr是通过setAttribute实现,而jQuery.prop则会直接访问DOM对象的property

详细介绍的地址

 

74、Oject对象上的方法

1)Object.create():创建一个具有指定原型,且可选择性地包含指定属性的对象

// prototype--必需,要用作原型的对象,可以为 null
// descriptors---可选,包含一个或多个属性描述符的 JavaScript 对象
// 返回值:一个具有指定的内部原型且包含指定的属性(如果有)的新对象
Object.create(prototype, descriptors)
var firstLine = { x: undefined, y: undefined };

var secondLine = Object.create(Object.prototype, {
        x: {
                value: undefined, 
                writable: true, 
                configurable: true, 
                enumerable: true
            },
            y: {
                value: undefined, 
                writable: true, 
                configurable: true, 
                enumerable: true
            }
});

document.write("first line prototype = " + Object.getPrototypeOf(firstLine));
document.write("
"); document.write("second line prototype = " + Object.getPrototypeOf(secondLine)); // Output: // first line prototype = [object Object] // second line prototype = [object Object]

2)Object.defineProperties():将一个或多个属性添加到对象,并/或修改现有的多个属性的特性(取值或者赋值的时候触发set   get)

// object----必需,对其添加或修改属性的对象,可以是本机 JavaScript 对象或 DOM 对象
// descriptors----必需,包含一个或多个描述符对象的JavaScript对象,
// 每个描述符对象描述一个数据属性或访问器属性(set,get)
//返回值--已传递给函数的对象object
Object.defineProperties(object, descriptors)
var newLine = "
"; var obj = {}; Object.defineProperties(obj, { newDataProperty: { value: 101, writable: true, enumerable: true, configurable: true }, newAccessorProperty: { set: function (x) { console.log("in property set accessor" + newLine); this.newaccpropvalue = x; }, get: function () { console.log("in property get accessor" + newLine); return this.newaccpropvalue; }, enumerable: true, configurable: true } }); // Set the accessor property value. obj.newAccessorProperty = 10; console.log("newAccessorProperty value: " + obj.newAccessorProperty + newLine);

3)Object.defineProperty():将一个属性添加到对象,或修改现有的一个属性的特性

 

 

 

 

74、网络分层里的七层网络分别是什么

 

应用层:应用层、表示层、会话层(从上往下)(HTTP、FTP、SMTP、DNS)

传输层(TCP和UDP)

网络层(IP)

物理和数据链路层(以太网)

每一层的作用如下:

物理层:通过媒介传输比特,确定机械及电气规范(比特Bit)     以太网
数据链路层:将比特组装成帧和点到点的传递(帧Frame)        以太网
网络层:负责数据包从源到宿的传递和网际互连(包PackeT)     IP
传输层:提供端到端的可靠报文传递和错误恢复(段Segment)    TCP/UDP
会话层:建立、管理和终止会话(会话协议数据单元SPDU) 
表示层:对数据进行翻译、加密和压缩(表示协议数据单元PPDU)
应用层:允许访问OSI环境的手段(应用协议数据单元APDU)      HTTP  FTP SMTP

一些协议的理解

 

ICMP协议(Internet Control Message Protocol): 因特网控制报文协议。它是TCP/IP协议族的一个子协议,用于在IP主机、路由器之间传递控制消息。 
TFTP协议(Trivial File Transfer Protocol,简单文件传输协议): 是TCP/IP协议族中的一个用来在客户机与服务器之间进行简单文件传输的协议,提供不复杂、开销不大的文件传输服务
HTTP协议(HyperText Transfer Protocol)): 超文本传输协议,是一个属于应用层的面向对象的协议,由于其简捷、快速的方式,适用于分布式超媒体信息系统

 

DHCP协议(Dynamic Host Configuration Protocol): 动态主机配置协议,是一种让系统得以连接到网络上,并获取所需要的配置参数手段

网络协议的类型、优缺点、作用:https://blog.csdn.net/tangxiujiang/article/details/79573339  
HTTP2.0的特性:https://blog.csdn.net/tangxiujiang/article/details/79615924
http/https/tcp/udp的区别:https://blog.csdn.net/tangxiujiang/article/details/79629708  
TCP的三次握手:https://blog.csdn.net/tangxiujiang/article/details/78135322 

 

75、数据库连接池

数据库连接池负责分配、管理和释放数据库连接,它允许应用程序重复使用一个现有的数据库连接,而不是再重新建立一个;释放空闲时间超过最大空闲时间的数据库连接来避免因为没有释放数据库连接而引起的数据库连接遗漏。这项技术能明显提高对数据库操作的性能


 

 

75、说说mongoDB和MySQL的区别

1)MySQL是传统的关系型数据库,MongoDB则是非关系型数据库

2)MongoDB以二进制进行存储,对海量数据存储有着很明显的优势

与关系型数据库MySQL相比,MongoDB的优点有:

a) 弱一致性(最终一致),更能保证用户的访问速度

b) 文档结构的存储方式,能够更便捷的获取数据
 

75、有一张表叫做student,含有字段name   course   grade  ,然后找出每一个学生的最高成绩

SELECT name,course,MAX(grade) FROM student GROUP BY name

75、数据库中的外连接和内连接的区别

外连接不但返回符合连接条件和查询条件的数据行还返回不符合条件的一些行(即返回左(右)表中所有的数据行)

内连接返回连接表(交叉连接的结果表)中符合连接条件和查询条件的数据行

 

SQL中的连接-----外连接(左向外连接、右向外连接、完整外部连接)、内连接、全连接、笛卡尔积(交叉连接)

连接:在表关系的笛卡尔积数据记录中,按照相应字段值的比较条件进行选择,生成一个新的关系

笛卡尔积(交叉连接):cross join没有连接条件表关系返回的结果(结果为表1记录(记录 数num1)组合表2记录(记录数num2))-----记录数目为num1*num2。返回左表中所有行左表中的每一行与右表中的所有行组合

内连接(inner join):相等连接、自然连接。内联接使用比较运算符,根据每个表共有的列的值匹配两个表中的行。例如,检索 students和courses表中学生标识号相同的所有行。

select  field from a inner join b  on a.id=b.id

外连接:在 FROM子句中指定外联接时,可以由下列几组关键字中的一组指定:     
1)LEFT  JOIN或LEFT OUTER JOIN     
左向外连接结果集包括:  LEFT OUTER子句中指定的左表的所有行,而不仅仅是联接列所匹配的行。如果左表的某行在右表中没有匹配行,则在相关联的结果集行中右表的所有选择列表列均为空值

       
2)RIGHT  JOIN 或 RIGHT  OUTER  JOIN     
右向外联接是左向外联接的反向联接。将返回右表的所有行,如果右表的某行在左表中没有匹配行,则将为左表返回空值

       
3)FULL  JOIN 或 FULL OUTER JOIN
完整外部联接返回左表和右表中的所有行。当某行在另一个表中没有匹配行时,则另一个表的选择列表列包含空值。如果表之间有匹配行,则整个结果集行包含基表的数据值。  

 

例子:

 表person1                                                表jobandfamily

前端面试十_第1张图片                前端面试十_第2张图片

 

关系:person1.id = jobandfamily.parent_id

内连接:结果返回匹配条件的两个表的行组成的新行的表

SELECT person1.*,jobandfamily.* FROM person1 INNER JOIN jobandfamily ON   person1.id=jobandfamily.parent_id 

前端面试十_第3张图片

外连接:左连接、右连接、完全连接

左连接返回左表所有行,以及右表匹配的行(右表没有匹配则右表为null)组成的新行的表

SELECT person1.*,jobandfamily.* FROM person1 LEFT JOIN jobandfamily ON   person1.id=jobandfamily.parent_id 

前端面试十_第4张图片

右连接:(左连接的反向连接)返回右表所有行,以及左表匹配的行(左表没有匹配则左表为null)组成的新行的表

SELECT person1.*,jobandfamily.* FROM person1 RIGHT JOIN jobandfamily ON   person1.id=jobandfamily.parent_id 

前端面试十_第5张图片

完全连接:返回左表和右表中的所有行。当某行在另一个表中没有匹配行时,则另一个表的选择列表列包含空值。如果表之间有匹配行,则整个结果集行包含基表的数据值

注意:MySQL中没有full join操作,可以用并集(union)组合left join和right join的结果

SELECT * FROM person1 LEFT JOIN jobandfamily ON person1.id=jobandfamily.parent_id
UNION  
SELECT * FROM person1 RIGHT JOIN jobandfamily ON person1.id=jobandfamily.parent_id 

前端面试十_第6张图片

 

数据库的第一范式、第二范式、第三范式

数据描述术语对应表

概念设计 --------------- 逻辑设计

实体-----------------------记录

属性-----------------------字段(数据项)

实体集---------------------文件

实体标识符--------------关键码

 

关键码 
1) 超键:在关系中能唯一标识元组的属性或属性集称为关键模式的超键。 
2) 候选键不含有多余属性的超键称为候选键。也就是在候选键中在删除属性就不是键了。 
3) 主键:用户选作元组标识的候选键称为主键。一般不加说明,键就是指主键。 
4) 外键:如果模式R中属性K是其他模式的主键,那么K在模式R中称为外键。

 

完全依赖、部分依赖、传递依赖 
1)部分函数依赖:设X,Y是关系R的两个属性集合,存在X→Y(由X可以推出Y),若X’是X的真子集,存在X’→Y,则称Y部分函数依赖于X。 
举个例子:学生基本信息表R中(学号,身份证号,姓名)当然学号属性取值是唯一的,在R关系中,(学号,身份证号)->(姓名),(学号)->(姓名),(身份证号)->(姓名);所以姓名部分函数依赖于(学号,身份证号); 
2)完全函数依赖:设X,Y是关系R的两个属性集合,X’是X的真子集,存在X→Y,但对每一个X’都有X’!→Y,则称Y完全函数依赖于X。 
例子:学生基本信息表R(学号,班级,姓名)假设不同的班级学号有相同的,班级内学号不能相同,在R关系中,(学号,班级)->(姓名),但是(学号)->(姓名)不成立,(班级)->(姓名)不成立,所以姓名完全函数依赖与(学号,班级);

3)传递函数依赖:设X,Y,Z是关系R中互不相同的属性集合,存在X→Y(Y !→X),Y→Z,则称Z传递函数依赖于X。

例子:在关系R(学号 ,宿舍, 费用)中,(学号)->(宿舍),宿舍!=学号,(宿舍)->(费用),费用!=宿舍,所以符合传递函数的要求

学号->宿舍,宿舍->费用,从而可以推出学号->费用

 

第一范式的定义:第一范式的数据表必须是二维数据表,是指数据库的每一列都是不可分割基本数据项,强调列的原子性

比如数据库的电话号码属性里面不可以有固定电话和移动电话值,如下图: 

前端面试十_第7张图片

说明:在任何一个关系数据库中,第一范式(1NF)是对关系模式的基本要求,不满足第一范式(1NF)的数据库就不是关系数据库

(1)冗余度大(2)引起数据修改不一致(3)插入异常(4)删除异常

 

 

 

第二 范式的定义:2NF 第二范式建立在第一范式的基础上,即满足第二范式一定满足第一范式,第二范式要求数据表每一个实例或者行必须被唯一标识。除满足第一范式外还有两个条件,一是必须有一个主键;二是没有包含在主键中的列必须完全依赖于主键,而不能只依赖于主键的一部分。

每一行的数据只能与其中一列相关,即一行数据只做一件事。只要数据列中出现数据重复,就要把表拆分开来

举例来说:当数据表中是联合主键,但是有的列只依赖联合主键中的一个或一部分属性组成的联合主键,此时需要拆表才能复合第二范式

 

第三范式的定义:若某一范式是第二范式,且每一个非主属性都不传递依赖于该范式的候选键,则称为第三范式

即不能存在:非主键列 A 依赖于非主键列 B,非主键列 B 依赖于主键的情况

举例来说:Employee(emp_id,emp_name,emp_age,dept_id,dept_name,dept_info)(员工号,员工名字,年龄,部门号,部门名字,部门信息)

员工表emp_id能够唯一确定员工员工信息,但是dept_name可由dept_id唯一确定,此时,该表不符合第三范式,此时可以删除除了dept_id之外的其他部门信息,把所有部门信息单独建立一张部门表

 

BCNF

BCNF 在第三范式的基础上,数据库表中如果不存在任何字段对任一候选关键字段的传递函数依赖则符合第三范式。

(1)所有非主属性对每一个码都是完全函数依赖; 
(2)所有的主属性对于每一个不包含它的码,也是完全函数依赖; 
(3)没有任何属性完全函数依赖于非码的任意一个组合。

R属于3NF,不一定属于BCNF,如果R属于BCNF,一定属于3NF。

假设仓库管理关系表为StorehouseManage(仓库ID, 存储物品ID, 管理员ID, 数量),且有一个管理员只在一个仓库工作;一个仓库可以存储多种物品。这个数据库表中存在如下决定关系:

(仓库ID, 存储物品ID) →(管理员ID, 数量)

(管理员ID, 存储物品ID) → (仓库ID, 数量)

所以,(仓库ID, 存储物品ID)和(管理员ID, 存储物品ID)都是StorehouseManage的候选关键字,表中的唯一非关键字段为数量,它是符合第三范式的。但是,由于存在如下决定关系:

(仓库ID) → (管理员ID)

(管理员ID) → (仓库ID)

即存在关键字段决定关键字段的情况,所以其不符合BCNF范式

 

事务的4个特征--------原子性、一致性、持续性和隔离性

最快的进程间通信方式为----------共享内存

系统死锁-------操作系统中死锁是指多个进程在运行过程中因争夺资源而造成的一种僵局

 

 

 

77、什么样的前端代码才是好的?

高复用;低耦合;文件小;易维护;扩展性好

 

78、浏览器原生支持module吗?

不支持

78、实现三个div等分排在一行

1)使用flexbox,父元素主要设置display:flex,width和height;子元素主要设置flex:1.0(均分多个子元素所占父元素的宽度)




  
  


  

 

79、实现输出一个数组中第n大的数据

思路:用快速排序,将一个数组里面的元素按照升序排序,然后查找这个排序数组中的第n大元素

function theNthMaxElement(arr,n){  
    var len = arr.length;  
    if( len < n ){  
      return '输入的参数n的值超出数组元素个数'  
    }  
    var newArr = quickSort(arr); //升序排序  
    var index = n-1;  
    var temp = newArr[index];  


    return temp;  
}  
  
function quickSort(arr){  
  // 降序排序
  var len = arr.length;  
  if( len <= 1 ){  
    return arr;  
  }  
  
  var midIndex = Math.floor(len/2),  
    midElement = arr.splice(midIndex,1),  
    left = [],  
    right = [];  
  
  for( var i=0;i midElement ){  
      left.push(arr[i]);  
    }else{  
      right.push(arr[i]);  
    }  
  }  
  
  return quickSort(left).concat(midElement,quickSort(right));  
}  
  
var arr = [6,1,3];  
console.log(theNthMaxElement(arr,1)); 

79、将一天24小时按每半小划分成48段,我们用一个位图表示选中的时间区间,例如110000000000000000000000000000000000000000000000,

// 表示第一个半小时和第二个半小时被选中了,其余时间段都没有被选中,也就是对应00:00~01:00这个时间区间。一个位图中可能有多个不连续的

// 时间区间被选中,例如110010000000000000000000000000000000000000000000,表示00:00-1:00和02:00-02:30这两个时间区间被选中了

思路

1)字符串利用match()函数转变成数组,数组元素是字符串的每两位组成,reg=/\d{2}/g,arr=str.match(reg)

2)利用数组的forEach()函数对数组元素遍历

3)每个元素重复操作:对元素分成两个变量pre  next,如果pre=1,next=0表示前半段,此时需要针对分界线key=10书写结果元素格式;如果pre=0,next=1表示后半段,此时需要针对分界线key=9书写结果元素格式;如果pre=1,next=1表示完整字段,此时需要针对分界线key=9书写结果元素格式

// 示例输入:"110010110000000000000000000000000000000000000011"
// 示例输出:["00:00~01:00", "02:00~02:30"]
function timeBitmapToRanges(str){
  let result = [];
  let reg = /\d{2}/g;
  let arr = str.match(reg);

  arr.forEach(function(val,key){
    let arr2 = val.split('');
    let pre = parseInt(arr2[0]);
    let next = parseInt(arr2[1]);
    let text = '';

    if(pre===1 && next===0){
      if(key<10){
        text = '0' + key + ':00~' + '0' + key + ':30';
      }else {
        text = key + ':00~' + key + ':30';
      }
      result.push(text);
    }else if(pre===0 && next===1){
      if(key < 9){
        text = '0' + key + ':30~' + '0' + (key+1) + ':00';
      }else if(key === 9){
        text = '0' + key + ':30~' + (key+1) + ':00';
      }else{
        text =  key + ':30~' + (key+1) + ':00';
      }
      result.push(text);
    }else if(pre===1 && next===1){
      if(key < 9){
        text = '0' + key + ':00~' + '0' + (key+1) + ':00';
      }else if(key === 9){
        text = '0' + key + ':00~' + (key+1) + ':00';
      }else{
        text =  key + ':00~' + (key+1) + ':00';
      }
      result.push(text);
    } 
  })
  return result;
}

var str = "110010000000000000000000000000000000000000000000";
console.log(timeBitmapToRanges(str))

 

 

 

80、怎么实现从一个DIV左上角到右下角的移动,有哪些方法,都怎么实现

1)改变left值为window宽度-div宽度, top值为window高度-div高度

2)jquery的animate方法

3)css3的transition

 

81、判断数组有哪些方法

1)arr instanceof Array       //结果为boolean
2)arr.constructor == Array
3)Object.prototype.toString.call(arr) == '[Object Array]'

var arr = [1,2,3];
//方法一
if( arr instanceof Array ){
	console.log('true');
}

// 方法二
if( Object.prototype.toString.call(arr) == '[object Array]' ){
	console.log('true');
}
// 方法三
if( arr.constructor == Array ){
	console.log('true');
}

82、判断一个变量是String类型的方法

 

var str = 'erdsfsd';
if( typeof(str) === "string" ){
  console.log('1');
}

if(str.constructor === String){
  console.log('2');
}

 

82、什么是跨域?跨域有哪些解决方案?有什么不同

跨域出现的原因

浏览器的同源策略导致了跨域,即浏览器出于安全方面的考虑,在全局层面禁止当前页面加载或执行其它域的任何脚本。

什么因素触发跨域

当请求的url中的协议,域名,端口号三者任意一个与当前页面的url不同,则发生跨域问题。

 

简述原理与过程:首先在客户端注册一个callback, 然后把callback拼接到请求的url中。此时,服务器先生成一个function , function 名字就是传递过来的参数。最后将 json 数据直接作为该函数的参数,放置到 function 中,这样就生成了一段 js 语法的文档,返回给客户端。客户端浏览器,解析script标签,并执行返回的 javascript 文档,此时数据作为参数,传入到了客户端预先定义好的 callback 函数里。

另一种解释:

jsonp的原理:jsonp之所以能跨域,是因为他并不是发送ajax请求,没有使用XMLHttpRequest对象,他其实是利用动态创建的script标签,而script标签是没有同源策略限制的,可以跨域的。创建script标签,然后将其src,指向我们真实的服务端的地址,在这个地址的后面有一个参数比如calback=a,然后服务端可以解析到这个url,中的callback=a,服务端在返回的数据时,就会调用a方法,去包裹一段数据,然后返回这段js代码,相当于在前端去执行这个a方法。那么在前端发送请求之前,就要在window上去注册这个a方法,那么在服务端返回这个a方法执行的时候,就可以去之前在window上定义的a方法中获得数据了
 

详细介绍的网址:点击打开链接

https://blog.csdn.net/tangxiujiang/article/details/79568548

跨域解决方法:

1)jsonp

2)CORS:前后端协作设置请求头部,Access-Control-Allow-Origin:*    Access-Control-Allow-Methods等头部

3)服务器代理:前端给当前域的服务器发送请求,再由当前域的服务器与另外一个域的服务器进行通信,当前域服务器拿到数据在发送给前端

4)nginx反向代理:(nginx服务内部配置Access-Control-Allow-Origin:*)

 

83、多页面通信有哪些方案,各有什么不同?

web领域主要有以下两种实现方式:

1)获取句柄,定向通讯

2) 共享内存,结合轮询或者事件通知来完成业务逻辑

由于第二种原理更利于解耦业务逻辑,具体的实现方案比较多样

a) localstorge在一个标签页里被添加、修改或删除时,都会触发一个storage事件,通过在另一个标签页里监听storage事件,即可得到localstorge存储的值,实现不同标签页之间的通信

// A.html
localStorage.setItem('message', 'hello')

// B.html
window.onstorage = evt => {
// evt.key, evt.oldValue, evt.newValue
}

注意:storage事件只有在发生改变的时候才会触发,即重复设置相同值不会触发listener

优缺点:API简单直观,兼容性好,除了跨域场景下需要配合其他方案,无其他缺点

b) setTimeout + cookie:只能同域使用,而且污染cookie以后还而外增加ajax的请求同内容

 

84、元素垂直居中

1)单行行内元素:设置padding-bottom和padding-top;将height和line-height设为相等

2)多行行内元素:将元素转为display:table;vertical-align:middle;使用弹性布局display:flex;justify-content:center;align-items:center

 

85、 rem和em的区别

rem和em经常用于自适应布局 中

em 和 rem 单位之间的区别是浏览器根据谁来转化成px值 ,理解这种差异是决定何时使用哪个单元的关键

其中rem相对于页面根元素的字体大小来决定的,而em则根据使用它的元素的大小来决定的

1)rem 单位转化为像素大小取决于页面根元素的字体大小:根元素字体大小 * rem值

2)em单位转化为像素大小取决于使用它的元素的大小:使用em单位的元素的字体大小 * em值

 

86、图片的懒加载和预加载的原理

预加载:分析用户行为,在上一页提前将资源加载,在onload函数里面执行加载资源文件

在网页中,如果直接给一个img标签节点设置src属性,由于图片过大或者网络不佳,图片位置往往有段时间会是一片空白。所谓的预加载技术就是先用一张loading图片占位,然后用异步的方式加载图片(Image.onload()),等图片加载好了之后再填充到img节点里面。

懒加载:先将图片的地址存放在一个自定义的属性上,等到指定的事件触发的时候,将该属性上的值赋给src。这是因为当将图片的地址赋给src的时候,浏览器才会去加载该图片。

 

 

86、Array对象常用的方法:改变原数组和不改变原数组的方法

详细介绍地址:点击打开链接

https://blog.csdn.net/tangxiujiang/article/details/79612935

86、js字符串常用函数

1) toLowerCase() – 把字符串转换成小写字母,返回一个新的字符串

stringObject.toLowerCase()

2) toUpperCase() – 把字符串转成大写字母,返回一个新的字符串

stringObject.toUpperCase()

3) charAt() – 返回指定位置的字符

stringObject.charAt(index)

4) charCodeAt() – 返回指定位置的字符的 Unicode 编码。这个返回值是 0 - 65535 之间的整数

stringObject.charCodeAt(index)

str.codePointAt(index) – 返回指定位置字符的 Unicode 编码,可以针对32位编码的,修复charCodeAt()只能针对16位编码的问题

str.fromCodePoint()-----根据码位生成字符

 

5) indexOf() – 返回字符串中一个子串第一处出现的索引。如果没有匹配项,返回 -1 

stringObject.indexOf(searchvalue,fromindex)

6) lastIndexOf() – 返回字符串中一个子串最后一处出现的索引,如果没有匹配项,返回 -1

stringObject.lastIndexOf(searchvalue,fromindex)

字符串中substring、substr、slice区别

7) substr() 函数 -- 返回从string的startPos位置,长度为length的字符串。start=-1则取最后一个元素,start=-2则取倒数第二个元素。

将第一个负的参数加上length,第二个负的参数置为0;如果length大于字符串的长度,则返回实际的个数

stringObject.substr(start,length)

8) substring() – 返回字符串的一个子串,不包括stop;

会把所有负的参数置为0;

start=stop返回空串;

strat>stop,则先交换位置在查询;

stringObject.substring(start,stop)

9) slice() – 提取字符串的一部分,并返回一个新字符串。不包括stop的元素;

start和stop都允许是负值,先和长度相加在截取(如果start>stop,不会发生交换)

stringObject.slice(start,stop)

10) split() – 把一个字符串分割成字符串数组

stringObject.split(separator,howmany)

11) concat() – 将两个或多个字符的文本组合起来,返回一个新的字符串

str.concat(string2[, string3, ..., stringN])

12) match() – 在字符串内检索指定的值,或找到一个或多个正则表达式的匹配

返回存放匹配结果的数组。该数组的内容依赖于 regexp 是否具有全局标志 g;没有匹配成功则返回null

13) replace() – 在字符串中用一些字符替换另一些字符,或替换一个与正则表达式匹配的子

stringObject.replace(regexp/substr,replacement)

14) search() –检索字符串中指定的子字符串,或检索与正则表达式相匹配的子字符串。

返回stringObject 中第一个与 regexp 相匹配的子串的起始位置(忽略g);没匹配返回-1

stringObject.search(regexp)

15) length – 返回字符串的长度,所谓字符串的长度是指其包含的字符的个数

字符串的子串识别

16) str.includes(子串,startIndex)– --参数子串是必须,startIndex开始检索的位置,返回boolean类型,不指定则从0开始

17) str.startsWith(子串,startIndex)– --参数子串是是必须,startIndex开始检索的位置,返回boolean类型,不指定则从0开始

18) str.endsWith(子串,tmpIndex)– --参数参数子串是是必须,字符串长度-tmpIndex开始检索,不指定从末尾开始匹配

19) str.repeat(num)– --将字符串重复的次数

console.log( 'a'.repeat(0) );  //空字符串
console.log( 'a'.repeat(1) );  //'a'
console.log( 'a'.repeat(2) );  //'aa'

使用详情可以参考网址:点击打开链接

 

 

 

87、框架问题

1)MVVM和mvc的区别是什么?原理是什么

mvc的界面和逻辑关联紧密,数据直接从数据库读取,必须通过Controller来承上启下,通信都是单向的。mvvm的View 和 ViewModel可以互相通信,界面数据从viewmodel中获取

2)父子组件怎么通信的?

a)vue:父组件是通过props属性给子组件传递数据

在父组件中调用子组件并且绑定属性data

 

在子组件scroll.vue文件的props接收父组件中传递过来的数据data对象

props: {
   data: {
      type: Array,
      default() {
         return []
      }
   }
}

 b)子组件是通过事件机制向父组件传递数据,也就是子组件通过$emit向父组件派发一个事件

在子组件的methods里面定义一个方法:通过me.$emit('scroll',pos)将数据pos传给父组件

_initScroll() {
      if (!this.$refs.wrapper) {
        //保证DOM已经渲染完成
        return
      }
      this.scroll = new BScroll(this.$refs.wrapper, {
        click: this.click,
        probeType: this.probeType
      })
      //如果要监听scroll事件
      if (this.listenScroll) {
        //保留vue实例
        let me = this
        this.scroll.on('scroll', (pos) => {
          //将子组件的数据传给父组件,这里的事件名scroll要和listView.vue中在template中元素绑定的事件名一样
          me.$emit('scroll', pos)
        })
      }
    }

在父组件引用标签上监听该事件@scroll='scroll'

 

然后再父组件的methods中定义该方法,用从子组件中传过来的数据进行一些处理

   scroll(pos) {
      //根据pos.y的值设置bg-layer的偏移量,在watch里面设置滚动值
      this.scrollY = pos.y
    }

c)兄弟间通信:通过vuex,把组件的共享状态抽取出来,以一个全局单例模式管理,当组件引用store中的状态变量时候,store中相应状态变量发生变化的时候,就会自动映射到组件中并完成更新

d)通过ref属性,获取到子组件中的DOM元素

例如:

 

通过this.$refs.list.el可以获取到scroll组件中的根节点,也就是DOM节点,这个时候可以给DOM节点设置css属性

this.$refs.list.el.bottom = '12px' 

e)通过ref属性,获取到子组件中定义的方法

 

如b)中的例子,在父组件要获取子组件的refresh方法

 

this.$refs.list.refresh()

 

 

react:props传递,父给子传一个回调函数,将数据传给父亲处理

 

3)兄弟组件怎么通信的?

vuex:建立一个vue实例,emit触发事件,on监听事件

react:子A -> 父 -> 子B

4)生命周期函数有哪些?怎么用?

vue:beforecreate-----el和data 并未初始化;created---完成了 data 数据的初始化,el没有;beforeMount----完成了el和data初始化,但是el还是挂载在之前虚拟的DOM上,;mounted---el完成挂载;befoeUpdate、updated---更新;beforeDestroy、destroyed----Vue实例已经解除了事件监听以及和DOM的绑定

 

react:初始化阶段、运行阶段、销毁阶段

a) 初始化getDefaultProps()和getInitialState()初始化    

b) componentWillMount()在组件即将被渲染到页面

c) render() 组件渲染

d) componentDidMount()组件被渲染到页面上

e) 运行中shouldComponentUpdate() componentWillUpdate() render() componentDidUpdate() 

f) 销毁componentWillUnmount()

 

88、css中position的值

css的属性position规定元素的定位类型,任何元素都可以定位,对于absolute和fixed定位的元素会生成一个块级框,而不论本身是什么类型并且脱离文档流,相对定位元素会相对于他在正常流中的默认位置偏移

1)absolute:生成绝对定位的元素,相对于static定位以外的第一个父元素进行定位(如果没有则相对于body定位),定位位置通过top,bottom,left,right规定

2)fixed:生成绝对定位的元素,相对于浏览器窗口定位,即固定在浏览器窗口的某一个位置,即使浏览器窗口滚动,该元素的位置也不会发生变化,定位位置通过top,bottom,left,right

3)relative:生成相对定位的元素,相对于其正常位置进行定位,可以设置top,bottom,left,right

4)static:默认值,没有进行定位,元素出现在正常流中,忽略top   left   right   bottom   z-index的声明

5)inherit:继承父元素的position属性,但需要注意的是IE8以及往前的版本都不支持inherit属性

6)sticky:生成粘性定位的元素,在屏幕范围(viewport)时该元素的位置并不受到定位影响(设置是top、left等属性无效),当该元素的位置将要移出偏移范围时,定位又会变成fixed,根据设置的left、top等属性生成固定位置的效果。元素固定的相对偏移是相对于离它最近的具有滚动框的祖先元素,如果祖先元素都不可以滚动,那么是相对于viewport来计算元素的偏移量

sticky生效规则:

1、须指定 top, right, bottom 或 left 四个阈值其中之一,才可使粘性定位生效,否则其行为与相对定位相同(top  bottom同时设置top优先级高;left   right同时设置left的优先级高)

2、设定为 position:sticky 元素的任意父节点的 overflow 属性必须是 visible,否则 position:sticky 不会生效。要不然不会有先滚动然后固定的情况

3、如果 position:sticky 元素的任意父节点定位设置为 position:relative | absolute | fixed,则元素相对父元素进行定位,而不会相对 viewprot 定位

4、达到设定的阀值

 

sticky应用:实现头部导航栏的固定;实现侧边导航栏的固定

 

兼容性不好

在ios上很流畅,但是再安卓上,安卓4.4.4以下全军覆没,莫名其妙在安卓7上也跪。

在微信浏览器上,滚动并不是即时的,它需要等滚动完,scroll事件才触发,这样通过js计算距离屏幕顶端距离,然后fixed和relative定位切换,并不流畅,会卡顿。而sticky却非常流畅

 

 

90、css3的动画和js动画的区别

1)代码复杂度:js动画的代码相对复杂些

2)动画运行时对动画的控制程度上:js能够让动画暂停、取消、终止、开始,而css动画不能添加事件

3)动画性能:js动画多了一个js解析的过程,性能不如css动画好

4)兼容性:js无需考虑兼容性问题,但是css需要考虑兼容性问题

 

90、css3的动画和jquery的动画的区别

1)css3中的transition和animation动画都是基于css实现的,属于css范畴之内,并没有涉及到任何语言操作,效率略高于jQuery中的animate()函数,但兼容性差

2)jQuery中的animate()函数可以简单的理解为css样式的“逐帧动画”,是css样式不同状态的快速切换的结果。效率略低于css3动画执行效率,但是兼容性好

推荐在兼容性要求不是很高的情况下尽量使用css3动画,在需要兼容性很好并且有复杂的事件响应的情况下使用jQuery中的animate()函数。
3)css3 使用 GPU,jQuery 使用 CPU
4)css3 animation 支持的 css 属性比 jQuery 多

 

 

91、什么是弹性布局?弹性布局有哪些属性

1)flex布局(弹性布局):可以简便、完整、响应式地实现各种页面布局,目前得到所有浏览器的支持。设为flex布局之后,其子元素float  vertical-align  clear属性失效

任何一个容器(块级元素)都可以定义成flex布局:

.box{
  display: -webkit-flex; /* Safari */
  display: flex;
}

行内元素也可以定义成flex布局:

 

.box{
  display: -webkit-inline-flex; /* Safari */
  display: inline-flex;
}


1)容器(弹性布局)的属性:6个

a) flex-direction:决定主轴的方向(项目的排列方向)

 

.box {
  flex-direction: row | row-reverse | column | column-reverse;
}

row(默认值):主轴为水平方向,起点在左端
row-reverse:主轴为水平方向,起点在右端
column:主轴为垂直方向,起点在上沿
column-reverse:主轴为垂直方向,起点在下沿

b) flex-wrap:如果一条轴线排不下了,该如何换行

.box{
  flex-wrap: nowrap | wrap | wrap-reverse;
}

nowrap(默认值):不换行

wrap:换行,第一行在上方

warp-reverse:换行,第一行在下方

c) flex-flow:是flex-direction和flex-wrap属性的简写,默认值row nowrap

.box {
  flex-flow:  || ;
}

d) justify-content:定义项目在主轴上的对齐方式

 

.box {
  justify-content: flex-start | flex-end | center | space-between | space-around;
}

flex-start(默认值):左对齐
flex-end:右对齐
center: 居中
space-between:两端对齐,项目之间的间隔都相等。

space-around:每个项目两侧的间隔相等。所以,项目之间的间隔比项目与边框的间隔大一倍

 

e) align-items:定义项目在交叉轴上如何对齐

.box {
  align-items: flex-start | flex-end | center | baseline | stretch;
}

flex-start:交叉轴的起点对齐
flex-end:交叉轴的终点对齐
center:交叉轴的中点对齐
baseline: 项目的第一行文字的基线对齐

stretch(默认值):如果项目未设置高度或设为auto,将占满整个容器的高度

f) align-content:定义了多根轴线的对齐方式。如果项目只有一根轴线,该属性不起作用

flex-start:与交叉轴的起点对齐。
flex-end:与交叉轴的终点对齐。
center:与交叉轴的中点对齐。
space-between:与交叉轴两端对齐,轴线之间的间隔平均分布。
space-around:每根轴线两侧的间隔都相等。所以,轴线之间的间隔比轴线与边框的间隔大一倍。
stretch(默认值):轴线占满整个交叉轴

2)项目的属性:6个

a) order:定义项目的排列顺序。数值越小,排列越靠前,默认为0

.item {
  order: ;
}

b) flex-grow:定义项目的放大比例,默认为0,即如果存在剩余空间,也不放大(内容等分)

.item {
  flex-grow: ; /* default 0 */
}

如果所有项目的flex-grow属性都为1,则它们将等分剩余空间(如果有的话)。如果一个项目的flex-grow属性为2,其他项目都为1,则前者占据的剩余空间将比其他项多一倍

c) flex-shrink:定义了项目的缩小比例,默认为1,即如果空间不足,该项目将缩小  (宽度不足的时候内容的缩放)

.item {
  flex-shrink: ; /* default 1 */
}

d) flex-basis:定义了在分配多余空间之前,项目占据的主轴空间(main size)。浏览器根据这个属性,计算主轴是否有多余空间。它的默认值为auto,即项目的本来大小.(占位空间)

 

.item {
  flex-basis:  | auto; /* default auto */
}

e) flex:是flex-grow, flex-shrink 和 flex-basis的简写,默认值为0 1 auto。后两个属性可选

 

.item {
  flex: none | [ <'flex-grow'> <'flex-shrink'>? || <'flex-basis'> ]
}

f) align-self:允许单个项目有与其他项目不一样的对齐方式,可覆盖align-items属性。默认值为auto,表示继承父元素的align-items属性,如果没有父元素,则等同于stretch

详细讲解链接:点击打开链接

 

使用flex布局,让低栏出现在页面的底部,无论主内容有多少---父容器设置display:flex;  flex-direction:column;  中间容器设置flex:1




  
  
 

    
我是头部
我是中间内容
我是底部

让3个容器均分父容器的宽度排列:父容器设置:display:flex;3个子容器设置flex:1

父容器有两个子元素,一个子元素是固定宽度,另一个元素自动占满剩余的空间:父容器设置display:flex;固定宽度的子元素:flex:0 0 200px;width:200px;另一个子元素:flex:1

 

93、分域名存放图片的原因,以及这样做的好处

浏览器的并发请求数目限制是针对同一域名的,超过限制数目的请求会被阻塞
浏览器并发请求个数限制,分域名可以同时并发请求大量图片

 

94、页面的加载顺序

html顺序加载,其中js会阻塞后续DOM和资源的加载css不会阻塞dom和资源的加载,但是会阻塞js的加载

浏览器会使用prefetch对引用的资源提前下载

关于外部脚本需要注意一下几点:

1)没有 defer或async的外部脚本,浏览器会立即加载并执行指定的脚本

2)有async的外部脚本,则下载异步,执行同步,加载完就执行

3)有defer的脚本,异步加载,在所有资源加载完成之后才执行


95、生成10个数值在20-50的之间的随机数

 

var arr = [];
for(var i = 0;i<10;i++){
    var num = Math.round(Math.random()*30 + 20);
     arr.push(num);
}
console.log(arr);

 

95、js或者css缓存存在的问题以及解决方法

 

问题:修改了的css,js在浏览器没有得到更新

解决方法:使用前端构建工具gulp、webpack给引入的css或者js加上版本号并在内容发生变化的时候,修改版本号

 

96、websocket和ajax轮询相比的优缺点

 

WebsocketHTML5中提出的建立在单个TCP连接上的全双工通信协议客户端与服务器端可以向另一方发送/响应请求,实现服务器的推送功能。其优点就是,只要建立一次连接,就可以连续不断的得到服务器推送的消息节省带宽和服务器端的压力

ajax轮询
模拟长连接就是每隔一段时间(0.5s)就向服务器发起ajax请求,查询服务器端是否有数据更新。其缺点显而易见,每次都要建立HTTP连接,即使需要传输的数据非常少,所以这样很浪费带宽

 

97、实现一个秒针绕一点转动的效果

animation: move 60s infinite steps(60); 
/*设置旋转的中心点为中间底部*/ 
transform-origin: center bottom; 
/*旋转从0度到360度*/ 
@keyframes move { 
    from { 
        transform: rotate(0deg); 
    } 
    to { 
        transform: rotate(360deg); 
    } 
} 

 

 

你可能感兴趣的:(面试题)