2020-09-09面试题

html
1、 html5新特性

用于绘画的 canvas 元素

用于媒介回放的 video 和 audio 元素

对本地离线存储的更好的支持,比如:sessionStorage、cookie、localstorage

新的特殊内容元素,比如 article、footer、header、nav、section

新的表单控件,比如 calendar、date、time、email、url、search

新增的语义化标签:

:简短、描述性、唯一(提升搜索引擎排名)。
:页眉通常包括网站标志、主导航、全站链接以及搜索框 :标记导航,仅对文档中重要的链接群使用。
:页面主要内容,一个页面只能使用一次。如果是web应用,则包围其主要功能。
:包含像报纸一样的内容= =||是这么理解的,表示文档、页面、应用或一个独立的容器。
:具有相似主题的一组内容,比如网站的主页可以分成介绍、新闻条目、联系信息等条 :指定附注栏,包括引述、侧栏、指向文章的一组链接、广告、友情链接、相关产品列表
:页脚,只有当父级是body时,才是整个页面的页脚。 :指定细则,输入免责声明、注解、署名、版权。 :表示内容重要性 :突出显示文本(yellow),提醒读者 :指明引用或者参考,如图书的标题,歌曲、电影、等的名称,演唱会

 

2、对html5语义化的理解

  • 什么是HTML语义化?
    根据内容的结构化(内容语义化),选择合适的标签(代码语义化)便于开发者阅读和写出更优雅的代码的同时让浏览器的爬虫和机器很好地解析。
  • 为什么要语义化?
    (1)html语义化让页面内容结构更加清晰,便于浏览器搜索引擎解析,更容易阅读;
    (2)利于搜索引擎的爬虫,利于SEO;
    (3)使阅读源码的人对网站更容易将网站分块,便于阅读维护理解;
    (4)便于团队开发和维护,语义化更具可读性,是下一步吧网页的重要动向,遵循W3C标准的团队都遵循这个标准,           可以减少差异化。

3、什么是 HTML5?

HTML5 是最新的 HTML 标准。

HTML5 是专门为承载丰富的 web 内容而设计的,并且无需额外插件。

HTML5 拥有新的语义、图形以及多媒体元素。

HTML5 提供的新元素和新的 API 简化了 web 应用程序的搭建。

HTML5 是跨平台的,被设计为在不同类型的硬件(PC、平板、手机、电视机等等)之上运行。

css


1、css选择器有哪些

1、标签选择器:以标签名开头,选择所有div元素

2、类选择器:给标签取class名,以点(.)加class名开头,选择所有该class名的元素

3、id选择器:给标签取id名,以#加id名开头,具有唯一性,选择”id = ‘wrap’”的元素

4、子选择器:以>隔开父子级元素,(模块名>模块名,修饰>前模块内的子模块)

5、包含选择器:以空格隔开包含关系的元素,(模块名模块名,修饰空格前模块内所有该模块)

6、兄弟选择器:以~隔开兄弟关系的元素(模块名~模块名 修饰~前模块往下的所有兄弟模块)

7、相邻选择器:以+隔开相邻关系的元素(模块名+模块名 修饰加号前模块往下的相邻的模块 只一个)

8、全局选择器:以*开头(星号标在大括号前,修饰了包含body所有的标签)

9、群选择器:以,分隔(逗号分隔开需要修饰的模块名)

10、属性选择器:[] ([type=text]修饰属性为type=text的模块)

11、伪类选择器
(1) li:first-child{} (修饰第一个li)
(2) li:last-child{} (修饰最后一个li)
(3) li:nth-child{} (修饰第()个li)
(4) li:not(){} (不修饰第()个li,括号里面可以填以上的选择器)


2、css权重问题

分别以1000、100、10、1四个权值系数对CSS选择器进行权重计算。

选择器类别 说明 权重表示 权值表示
行内样式 行内只有一个 style = "" (1.0.0.0)  1000
id选择器 selector中使用了几个id,即#的个数 (0.1.0.0)  100
类选择器

类,伪类,以及属性的个数

如: .outerClass .buttonClass[type="button"]:hover{}

选择器中有2个类,1个属性,1个伪类

(0.0.1.0)  10
元素选择器

伪元素和标签元素的个数,如: p:first-child

选择器中有一个标签元素p和一个伪元素first-child

(0.0.0.1)  1

 

 

3、position三个属性的区别

 static:为默认属性,不发生定位。
 relative:相对原始位置定位且原始位置依然存在。
 absolute:相对于最近的定位祖先(非static)的内边距边界定位且原始位置消失,内容也会随之发生变化。

4、css3新特性

1,@font-face加载字体样式,
2,文字渲染text-decoration,text-fill-color:文字内部填充颜色,text-stroke-color:文字边框填充颜色,text-stroke-width:文字边界宽度。
3,css3的多列布局 column-count:表示布局几列。column-rule:表示列与列之间的间隔条的样式 column-gap:表示列于列之间的间隔
4,边框圆角的布局。border-radius:50px;
5,css3的渐变效果, (gradient)
6,css3的阴影效果图 (shadow反射和reflect反射效果)
7,css3的多背景图片
8,css3的动画效果 animation

 5、css盒子模型

盒子模型分为ie盒子模型和w3c盒子模型,

1、ie的盒子模型包括:margin(外边距),padding(内边距),边框(border),内容(content)

     ie的width=content+padding+border

2、w3c的盒子模型包括(margin(外边距),padding(内边距),边框(border),内容(content)

      w3c的width=content

6、css不知道宽高的情况下如何居中(说上2-3个方法)

16种方法实现水平居中垂直居中


7、对BFC理解(考到

        BFC全称为Block Formatting Context,即“块级格式化上下文”,它是页面中相对独立的一块渲染区域,它决定了内部的子元素如何进行摆放和定位,以及区域内部元素和区域外部元素之间的相互作用关系。

BFC触发/创建条件:

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

BFC特性:

  1. 内部的Box会在垂直方向上一个接一个放置。
  2. Box垂直方向的距离由margin决定,属于同一个BFC的两个相邻Box的margin会发生重叠。=>给单独的box设置overflow:hidden
  3. 每个元素的margin box 的左边,与包含块border box的左边相接触。
  4. BFC的区域不会与float box重叠。(可用于清浮动)
  5. BFC是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素。
  6. 计算BFC的高度时,浮动元素也会参与计算。

8、link @import导入css区别

  1. link是XHTML标签,除了加载CSS外,还可以定义RSS等其他事务;@import属于CSS范畴,只能加载CSS
  2. link引用CSS时,在页面载入时同时加载;@import需要页面网页完全载入以后加载
  3. link无兼容问题;@import是在CSS2.1提出的,低版本的浏览器不支持
  4. link支持使用Javascript控制DOM去改变样式;而@import不支持

9、rem em 区别 vw和 vh问题

  • px像素(Pixel)。相对长度单位。像素px是相对于显示器屏幕分辨率而言的。
  • em是相对长度单位。相对于当前对象内文本的字体尺寸
举个例子:
比如说当前容器`font-size:16px;`则`1em`就等于16px;
  • rem 是CSS3新增的一个相对单位(相对于根元素的),使用方法就是
浏览器的默认字体是16px,那么`1rem=16px`以此类推计算12px=0.75rem,10px=0.625rem,2rem=32px;
这样使用很复杂。
  • vw——viewpoint width,视窗宽度,1vw等于视窗宽度的1%;

    ​​​​vh——viewpoint height,视窗高度,1vh等于视窗高度的1%;

11、行内元素有哪些?块级元素与那些?

块级元素:div/p/form/ul/li/ol/hr/fieldset/table/dd/dt/dl

行内元素:span/strong/a/b/em/img/input/lable/small/sub

12、CSS3文本效果 

(1)text-shadow 文本阴影

        text-shadow: 5px 5px 5px #FF0000;

(2)box-shadow 盒子阴影

           box-shadow: 10px 10px 5px #888888;

(3)text-overflow 文本溢出

          white-space: nowrap;

          width: 200px;

          overflow: hidden;

          text-overflow: ellipsis;

(4)word-wrap 换行

          word-wrap:break-word;

(5)word-break 单词拆分换行

           word-break: break-all; 

12、请写出你使用过的浏览器?并写出浏览器的内核?

IE(内核:trident); 
火狐浏览器mozilla firefox (内核:gecko) 
谷歌浏览器chrome(内核:webkit)    
opera浏览器(内核:presto) 

13、css3清除浮动的方式? 

在清除bai浮动前我们要了解两个重要的定义:

      浮动的定义:使元素脱离文zhi档流,按照指定方向发生移动dao,遇到父级边界或者相邻的浮动元素停了下来。
      高度塌陷:浮动元素父元素高度自适应(父元素不写高度时,子元素写了浮动后,父元素会发生高度塌陷)

清除浮动的属性clear
     clear:left | right | both | none | inherit:元素的某个方向上不能有浮动元素
     clear:both:在左右两侧均不允许浮动元素。

 具体清楚浮动的方法主要一下几种:

1、clear清除浮动(添加空div法)
      在浮动元素下方添加空div,并给该元素写css样式: {clear:both;height:0;overflow:hidden;}
2、给浮动元素父级设置高度
     我们知道了高度塌陷是应为给浮动元素的父级高度是自适应导致的,那么我们给它的设置适当的高度就可以解决这个问题了。
     缺点:在浮动元素高度不确定的时候不适用
3、方法:以浮制浮(父级同时浮动)
      何谓“以浮制浮”呢?就是**让浮动元素的父级也浮动**。
     缺点:需要给每个浮动元素父级添加浮动,浮动多了容易出现问题。
4、方法:父级设置成inline-block
     缺点:父级的margin左右auto失效,无法使用margin: 0 auto;居中了
5、 br 清浮动


br 标签自带clear属性,将它设置成both其实和添加空div原理是一样的。
 问题:不符合工作中:结构、样式、行为,三者分离的要求。
6、给父级添加overflow:hidden 清浮动方法;
     问题:需要配合 宽度 或者 zoom 兼容IE6 IE7
     overflow: hidden;*zoom: 1;
7、万能清除法 after伪类 清浮动(现在主流方法,推荐使用)  

选择符:after{ 
      content:"."; 
      clear:both; 
      display:block; 
      height:0; 
      overflow:hidden; 
      visibility:hidden;
 }

同时为了兼容 IE6,7 同样需要配合zoom使用例如:

.clear:after{
  content:'';
  display:block;
  clear:both;
  height:0;
  overflow:hidden;
  visibility:hidden;
}
.clear{
   zoom:1;
}

需要注意的东西:
    after伪类: 元素内部末尾添加内容;
    :after{content"添加的内容";} IE6,7下不兼容
zoom 缩放
      a、触发 IE下 haslayout,使元素根据自身内容计算宽高。
      b、FF 不支持;

js

1.js的数据类型

 基础的数据类型:
      1.字符串(string)
      2, 数字(number)
      3, 布尔  boolean
      4,object
      5,null
      6,undefined

 复合的数据类型:
    1,object对象

    2,function  构造函数

    3,array数组

1、es6合并对象的方法 =>深拷贝

方法一:

let o1 = { a: 1, b: 2, c: 3 };
let o2 = {...o1, d: 4}; // o2 = { a: 1, b: 2, c: 3, d: 4 }
let arr1 = [0, 1, 2];
let arr2 = [...arr1, 3]; // arr2 = [0, 1, 2, 3]

方法二:

let o1 = { a: 1, b: 2, c: 3 };
let o2 = Object.assign({}, o1, { d: 4 }); // o2 = { a: 1, b: 2, c: 3, d: 4 };

2、深拷贝和浅拷贝是什么?区别是什么?

 浅复制 —-只是拷贝了基本类型的数据,而引用类型数据,复制后也是会发生引用,我们把这种拷贝叫做“(浅复制)浅拷贝”,换句话说,浅复制仅仅是指向被复制的内存地址,如果原地址中对象被改变了,那么浅复制出来的对象也会相应改变。

深复制 —-在计算机中开辟了一块新的内存地址用于存放复制的对象。

浅拷贝的明显特征为:多个引用指向了同一块堆内存空间,任意改变一个引用都会导致其他引用的值发生变化。

深拷贝的明显特征为:在内存中又开辟了新的一块空间,指向了不同的内存块,改变一个引用是不会影响另外一个引用的。

2、js数组方法有哪些   原文地址:https://www.cnblogs.com/obel/p/7016414.html

join()
push()和pop()
shift() 和 unshift()
sort()
reverse()
concat()
slice()
splice()
indexOf()和 lastIndexOf() (ES5新增)
forEach() (ES5新增)
map() (ES5新增)
filter() (ES5新增)
every() (ES5新增)
some() (ES5新增)
reduce()和 reduceRight() (ES5新增)
1、join()

join(separator): 将数组的元素组起一个字符串,以separator为分隔符,省略的话则用默认用逗号为分隔符,该方法只接收一个参数:即分隔符。

var arr = [1,2,3];
console.log(arr.join()); // 1,2,3
console.log(arr.join("-")); // 1-2-3
console.log(arr); // [1, 2, 3](原数组不变)
通过join()方法可以实现重复字符串,只需传入字符串以及重复的次数,就能返回重复后的字符串,函数如下:

function repeatString(str, n) {
return new Array(n + 1).join(str);
}
console.log(repeatString("abc", 3)); // abcabcabc
console.log(repeatString("Hi", 5)); // HiHiHiHiHi
2、push()和pop()

push(): 可以接收任意数量的参数,把它们逐个添加到数组末尾,并返回修改后数组的长度。 
pop():数组末尾移除最后一项,减少数组的 length 值,然后返回移除的项。

var arr = ["Lily","lucy","Tom"];
var count = arr.push("Jack","Sean");
console.log(count); // 5
console.log(arr); // ["Lily", "lucy", "Tom", "Jack", "Sean"]
var item = arr.pop();
console.log(item); // Sean
console.log(arr); // ["Lily", "lucy", "Tom", "Jack"]
3、shift() 和 unshift()

shift():删除原数组第一项,并返回删除元素的值;如果数组为空则返回undefined 。 
unshift:将参数添加到原数组开头,并返回数组的长度 。

这组方法和上面的push()和pop()方法正好对应,一个是操作数组的开头,一个是操作数组的结尾。

var arr = ["Lily","lucy","Tom"];
var count = arr.unshift("Jack","Sean");
console.log(count); // 5
console.log(arr); //["Jack", "Sean", "Lily", "lucy", "Tom"]
var item = arr.shift();
console.log(item); // Jack
console.log(arr); // ["Sean", "Lily", "lucy", "Tom"]
4、sort()

sort():按升序排列数组项——即最小的值位于最前面,最大的值排在最后面。

在排序时,sort()方法会调用每个数组项的 toString()转型方法,然后比较得到的字符串,以确定如何排序。即使数组中的每一项都是数值, sort()方法比较的也是字符串,因此会出现以下的这种情况:

var arr1 = ["a", "d", "c", "b"];
console.log(arr1.sort()); // ["a", "b", "c", "d"]
arr2 = [13, 24, 51, 3];
console.log(arr2.sort()); // [13, 24, 3, 51]
console.log(arr2); // [13, 24, 3, 51](元数组被改变)
为了解决上述问题,sort()方法可以接收一个比较函数作为参数,以便我们指定哪个值位于哪个值的前面。比较函数接收两个参数,如果第一个参数应该位于第二个之前则返回一个负数,如果两个参数相等则返回 0,如果第一个参数应该位于第二个之后则返回一个正数。以下就是一个简单的比较函数:

function compare(value1, value2) {
if (value1 < value2) {
return -1;
} else if (value1 > value2) {
return 1;
} else {
return 0;
}
}
arr2 = [13, 24, 51, 3];
console.log(arr2.sort(compare)); // [3, 13, 24, 51]
如果需要通过比较函数产生降序排序的结果,只要交换比较函数返回的值即可:

function compare(value1, value2) {
if (value1 < value2) {
return 1;
} else if (value1 > value2) {
return -1;
} else {
return 0;
}
}
arr2 = [13, 24, 51, 3];
console.log(arr2.sort(compare)); // [51, 24, 13, 3]
5、reverse()

reverse():反转数组项的顺序。

var arr = [13, 24, 51, 3];
console.log(arr.reverse()); //[3, 51, 24, 13]
console.log(arr); //[3, 51, 24, 13](原数组改变)
6、concat()

concat() :将参数添加到原数组中。这个方法会先创建当前数组一个副本,然后将接收到的参数添加到这个副本的末尾,最后返回新构建的数组。在没有给 concat()方法传递参数的情况下,它只是复制当前数组并返回副本。

var arr = [1,3,5,7];
var arrCopy = arr.concat(9,[11,13]);
console.log(arrCopy); //[1, 3, 5, 7, 9, 11, 13]
console.log(arr); // [1, 3, 5, 7](原数组未被修改)
从上面测试结果可以发现:传入的不是数组,则直接把参数添加到数组后面,如果传入的是数组,则将数组中的各个项添加到数组中。但是如果传入的是一个二维数组呢?

var arrCopy2 = arr.concat([9,[11,13]]);
console.log(arrCopy2); //[1, 3, 5, 7, 9, Array[2]]
console.log(arrCopy2[5]); //[11, 13]
上述代码中,arrCopy2数组的第五项是一个包含两项的数组,也就是说concat方法只能将传入数组中的每一项添加到数组中,如果传入数组中有些项是数组,那么也会把这一数组项当作一项添加到arrCopy2中。

7、slice()

slice():返回从原数组中指定开始下标到结束下标之间的项组成的新数组。slice()方法可以接受一或两个参数,即要返回项的起始和结束位置。在只有一个参数的情况下, slice()方法返回从该参数指定位置开始到当前数组末尾的所有项。如果有两个参数,该方法返回起始和结束位置之间的项——但不包括结束位置的项。

var arr = [1,3,5,7,9,11];
var arrCopy = arr.slice(1);
var arrCopy2 = arr.slice(1,4);
var arrCopy3 = arr.slice(1,-2);
var arrCopy4 = arr.slice(-4,-1);
console.log(arr); //[1, 3, 5, 7, 9, 11](原数组没变)
console.log(arrCopy); //[3, 5, 7, 9, 11]
console.log(arrCopy2); //[3, 5, 7]
console.log(arrCopy3); //[3, 5, 7]
console.log(arrCopy4); //[5, 7, 9]
arrCopy只设置了一个参数,也就是起始下标为1,所以返回的数组为下标1(包括下标1)开始到数组最后。 
arrCopy2设置了两个参数,返回起始下标(包括1)开始到终止下标(不包括4)的子数组。 
arrCopy3设置了两个参数,终止下标为负数,当出现负数时,将负数加上数组长度的值(6)来替换该位置的数,因此就是从1开始到4(不包括)的子数组。 
arrCopy4中两个参数都是负数,所以都加上数组长度6转换成正数,因此相当于slice(2,5)。

8、splice()

splice():很强大的数组方法,它有很多种用法,可以实现删除、插入和替换。

删除:可以删除任意数量的项,只需指定 2 个参数:要删除的第一项的位置和要删除的项数。例如, splice(0,2)会删除数组中的前两项。

插入:可以向指定位置插入任意数量的项,只需提供 3 个参数:起始位置、 0(要删除的项数)和要插入的项。例如,splice(2,0,4,6)会从当前数组的位置 2 开始插入4和6。
替换:可以向指定位置插入任意数量的项,且同时删除任意数量的项,只需指定 3 个参数:起始位置、要删除的项数和要插入的任意数量的项。插入的项数不必与删除的项数相等。例如,splice (2,1,4,6)会删除当前数组位置 2 的项,然后再从位置 2 开始插入4和6。

splice()方法始终都会返回一个数组,该数组中包含从原始数组中删除的项,如果没有删除任何项,则返回一个空数组。

var arr = [1,3,5,7,9,11];
var arrRemoved = arr.splice(0,2);
console.log(arr); //[5, 7, 9, 11]
console.log(arrRemoved); //[1, 3]
var arrRemoved2 = arr.splice(2,0,4,6);
console.log(arr); // [5, 7, 4, 6, 9, 11]
console.log(arrRemoved2); // []
var arrRemoved3 = arr.splice(1,1,2,4);
console.log(arr); // [5, 2, 4, 4, 6, 9, 11]
console.log(arrRemoved3); //[7]
9、indexOf()和 lastIndexOf()

indexOf():接收两个参数:要查找的项和(可选的)表示查找起点位置的索引。其中, 从数组的开头(位置 0)开始向后查找。 
lastIndexOf:接收两个参数:要查找的项和(可选的)表示查找起点位置的索引。其中, 从数组的末尾开始向前查找。

这两个方法都返回要查找的项在数组中的位置,或者在没找到的情况下返回1。在比较第一个参数与数组中的每一项时,会使用全等操作符。

var arr = [1,3,5,7,7,5,3,1];
console.log(arr.indexOf(5)); //2
console.log(arr.lastIndexOf(5)); //5
console.log(arr.indexOf(5,2)); //2
console.log(arr.lastIndexOf(5,4)); //2
console.log(arr.indexOf("5")); //-1
10、forEach()

forEach():对数组进行遍历循环,对数组中的每一项运行给定函数。这个方法没有返回值。参数都是function类型,默认有传参,参数分别为:遍历的数组内容;第对应的数组索引,数组本身。

var arr = [1, 2, 3, 4, 5];
arr.forEach(function(x, index, a){
console.log(x + '|' + index + '|' + (a === arr));
});
// 输出为:
// 1|0|true
// 2|1|true
// 3|2|true
// 4|3|true
// 5|4|true
11、map()

map():指“映射”,对数组中的每一项运行给定函数,返回每次函数调用的结果组成的数组。

下面代码利用map方法实现数组中每个数求平方。

var arr = [1, 2, 3, 4, 5];
var arr2 = arr.map(function(item){
return item*item;
});
console.log(arr2); //[1, 4, 9, 16, 25]
12、filter()

filter():“过滤”功能,数组中的每一项运行给定函数,返回满足过滤条件组成的数组。

var arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
var arr2 = arr.filter(function(x, index) {
return index % 3 === 0 || x >= 8;
}); 
console.log(arr2); //[1, 4, 7, 8, 9, 10]

13、every()

every():判断数组中每一项都是否满足条件,只有所有项都满足条件,才会返回true。

var arr = [1, 2, 3, 4, 5];
var arr2 = arr.every(function(x) {
return x < 10;
}); 
console.log(arr2); //true
var arr3 = arr.every(function(x) {
return x < 3;
}); 
console.log(arr3); // false

14、some()

some():判断数组中是否存在满足条件的项,只要有一项满足条件,就会返回true。

var arr = [1, 2, 3, 4, 5];
var arr2 = arr.some(function(x) {
return x < 3;
}); 
console.log(arr2); //true
var arr3 = arr.some(function(x) {
return x < 1;
}); 
console.log(arr3); // false

15、reduce()和 reduceRight()

这两个方法都会实现迭代数组的所有项,然后构建一个最终返回的值。reduce()方法从数组的第一项开始,逐个遍历到最后。而 reduceRight()则从数组的最后一项开始,向前遍历到第一项。

这两个方法都接收两个参数:一个在每一项上调用的函数和(可选的)作为归并基础的初始值。

传给 reduce()和 reduceRight()的函数接收 4 个参数:前一个值、当前值、项的索引和数组对象。这个函数返回的任何值都会作为第一个参数自动传给下一项。第一次迭代发生在数组的第二项上,因此第一个参数是数组的第一项,第二个参数就是数组的第二项。

下面代码用reduce()实现数组求和,数组一开始加了一个初始值10。

var values = [1,2,3,4,5];
var sum = values.reduceRight(function(prev, cur, index, array){
return prev + cur;
},10);
console.log(sum); //25

3、map和forEach的区别(常常问)

相同点:

1.都是循环遍历数组中的每一项

2.每次执行匿名函数都支持三个参数,参数分别为item(当前每一项),index(索引值),arr(原数组)

3.匿名函数中的this都是指向window

4.只能遍历数组

不同点:

1.map()会分配内存空间存储新数组并返回,forEach()不会返回数据。

2.forEach()允许callback更改原始数组的元素。map()返回新的数组。

1、forEach()

forEach()针对每一个元素执行提供的函数,对数据的操作会改变原数组。

var arr1 = [0,2,4,6,8];
var newArr1 = arr1.forEach(function(item,index,arr1){
  console.log(this);
  console.log(arr1);
   arr1[index] = item/2; 
},this);
console.log(arr1);
console.log(newArr1);

使用场景:并不打算改变数据的时候,而只是想用数据做一些事情 ,比如存入数据库或则打印出来。

2、map

map()不会改变原数组的值,返回一个新数组,新数组中的值为原数组调用函数处理之后的值;

var arr = [0,2,4,6,8];
 var newArr = arr.map(function(item,index,arr){
            console.log(this);
            console.log(arr);
            return item/2;
 },this);
 console.log(newArr);

使用场景:map()适用于你要改变数据值的时候。不仅仅在于它更快,而且返回一个新的数组。

4、常用的数组排序方法(常问)

array.sort():

      sort() 方法用于对数组的元素进行排序,默认按“字母”升序。

字符串数组: 

arr.sort(); // 默认升序
arr.sort().reverse(); // 降序


数字数组:
arr.sort((a,b)=>{return a-b})  //  升序
arr.sort((a,b)=>{return b-a}) //  降序

    反转排序方法 reverse() 将一个数组中的元素的顺序反转排序。

//1. sort()进行反序
arr.sort((a,b)=>{return b-a})
//2. reverse()反序
arr.reverse()

5、js原型和原型链定义
6、promise原理

Promise是一个对象,保存着未来将要结束的事件,她有两个特征:

1、对象的状态不受外部影响,Promise对象代表一个异步操作,有三种状态,pending进行中,fulfilled已成功,rejected已失败,只有异步操作的结果,才可以决定当前是哪一种状态,任何其他操作都无法改变这个状态,这也就是promise名字的由来

2、一旦状态改变,就不会再变,promise对象状态改变只有两种可能,从pending改到fulfilled或者从pending改到rejected,只要这两种情况发生,状态就凝固了,不会再改变,这个时候就称为定型resolved,

7、http和https的区别

http是明文传输,容易被劫持不安全;https是加密后传输的相对较安全

https原理
客户端向服务端发送自身已经存在的加密算法列表和随机数A
服务端接收到了客户端的加密算法,然后综合比较选出比较合适的加密算法、公钥、数字证书和随机数B
客户端拿到服务端的数字证书验证有效性后生成一个随机字符串pre-master,
并根据随机数A、随机数B和pre-master计算出协商密钥,然后发送用公钥加密的pre-master和协商密钥加密的数据给服务端
服务端用私钥解密得到pre-master,然后和随机数A和随机数B计算出协商密钥来解密数据
服务端告诉客服端以后都用协商密钥加密数据

8、什么是闭包

闭包的实质是因为函数嵌套而形成的作用域链

闭包的定义即:函数 A 内部有一个函数 B,函数 B 可以访问到函数 A 中的变量,那么函数 B 就是闭包

9、轮播图原理
10、防抖和节流
11、es6新特性

const 与 let 变量
模板字面量
解构
对象字面量简写法
for...of循环
展开运算符
剩余参数(可变参数)
ES6箭头函数
javascript标准函数this
箭头函数和this
默认参数函数

12、深浅克隆

首先,克隆只针对对象、数组、函数等复杂数据。
浅克隆就是将栈内存中的引用复制一份,赋给一个新的变量,本质上两个指向堆内存中的同一地址,内容也相同,其中一个变化另一个内容也会变化(根本上改变的是同一个对象)。

深克隆就是创建一个新的空对象,开辟一块内存,然后将原对象中的数据全部复制过去,完全切断两个对象间的联系。

13、箭头函数与普通函数的区别

1.语法更加简洁、清晰;
2.箭头函数没有 prototype (原型),所以箭头函数本身没有this;
3.箭头函数不会创建自己的this
4.call | apply | bind 无法改变箭头函数中this的指向
5.箭头函数不能作为构造函数使用

14、bind、call、apply的区别

  • call(), 调用一个对象的一个方法以另一个对象替换当前对象。
  • apply(),应用某一个对象的一个方法,用另一个对象替换当前对象(继承性)

15、es6和es5的作用域区别
16、事件冒泡、事件委托、事件捕获

  • event.preventdefault()     阻止默认事件。
  • event.stoppropagation()  阻止事件冒泡,
  • 事件捕获指的是从document到触发事件的那个节点,即自上而下的去触发事件。
  • 相反的,事件冒泡是自下而上的去触发事件
  • 绑定事件方法的第三个参数,就是控制事件触发顺序是否为事件捕获。
    true,事件捕获;false,事件冒泡。默认false,即事件冒泡。

17、什么是暂时性死区
18、import和require的区别
19、数组去重方法
20、ajax和websocket的区别
21、jsonp原理

 JSONP就是通过加载远程js文件,远程的js文件中写有调用当前域中已经写好的js方法的语句,并且这个语句中包含需要传入的数据,这样这个数据就传入到了当前域。用一句话概括就是:通过js文件携带数据实现了数据的跨域访问
22、跨域方法有哪些

1. 浏览器的同源策略导致了跨域,用于隔离潜在恶意文件的重要安全机制

1. jsonp ,允许 script 加载第三方资源

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

3. cors 前后端协作设置请求头部,Access-Control-Allow-Origin 等头部信息

4. iframe 嵌套通讯,postmessage

1.porxy代理

定义和用法:proxy代理用于将请求发送给后台服务器,通过服务器来发送请求,然后将请求的结果传递给前端。
实现方法:通过nginx代理;

2.CORS 【Cross-Origin Resource Sharing】

定义和用法:是现代浏览器支持跨域资源请求的一种最常用的方式。
使用方法:一般需要后端人员在处理请求数据的时候,添加允许跨域的相关操作。
3.jsonp

定义和用法:通过动态插入一个script标签。浏览器对script的资源引用没有同源限制,同时资源加载到页面后会立即执行(没有阻塞的情况下)。
特点:通过情况下,通过动态创建script来读取他域的动态资源,获取的数据一般为json格式。
缺点:
1、这种方式无法发送post请求。
2、另外要确定jsonp的请求是否失败并不容易,大多数框架的实现都是结合超时时间来判定。

23、js处理异步的方式有哪些

1.回调函数(Callback)

2.Promise对象

3.async+await

4.发布/订阅

24、 get与post 通讯的区别

1. Get 请求能缓存,Post 不能

2. Post 相对 Get 安全一点点,因为Get 请求都包含在 URL 里,且会被浏览器保存历史纪录,Post 不会,但是在抓包的情况下都是一样的.

3. Post 可以通过 request body来传输比 Get 更多的数据,Get 没有这个技术

4. URL有长度限制,会影响 Get 请求,但是这个长度限制是浏览器规定的,不是 RFC 规定的

5. Post 支持更多的编码类型且不对数据类型限制

25、谈谈 This 对象的理解

1、this总是指向函数的直接调用者(而非间接调用者);
2、如果有new关键字,this指向new出来的那个对象;
3、在事件中,this指向触发这个事件的对象,特殊的是,IE中的attachEvent中的this总是指向全局对象Window;

this表示当前对象,this的指向是根据调用的上下文来决定的,默认指向window对象 

this 是执行上下文中的一个属性,它指向最后一次调用这个方法的对象。在实际开发中,this 的指向可以通过四种调用模式来判断。

第一种是函数调用模式,当一个函数不是一个对象的属性时,直接作为函数来调用时,this 指向全局对象。

 全局环境 

全局环境就是在里面,这里的this始终指向的是window对象,
   指向window对象

局部环境 

在全局作用域下直接调用函数,this指向window
 

 第二种是方法调用模式,如果一个函数作为一个对象的方法来调用时,this 指向这个对象。

对象函数调用,哪个对象调用就指向哪个对象



第三种是构造器调用模式,如果一个函数用 new 调用时,函数执行前会新创建一个对象,this 指向这个新创建的对象。

 使用 new 实例化对象,在构造函数中的this指向实例化对象。


第四种是 apply 、 call 和 bind 调用模式,这三个方法都可以显示的指定调用函数的 this 指向。

使用call或apply改变this的指向


 

    其中 apply 方法接收两个参数:一个是 this 绑定的对象,一个是参数数组。call 方法接收的参数,第一个是 this 绑定的对象,后面的其余参数是传入函数执行的参数。

    也就是说,在使用 call() 方法时,传递给函数的参数必须逐个列举出来。bind 方法通过传入一个对象,返回一个 this 绑定了传入对象的新函数。这个函数的 this 指向除了使用 new 时会被改变,其他情况下都不会改变。

这四种方式,使用构造器调用模式的优先级最高,然后是 apply 、 call 和 bind 调用模式,然后是方法调用模式,然后是函数调用模式。

26、什么是伪数组,如何将伪数组转成数组?

    伪数组:指的是具有 0 到 length-1 的属性,并且有 length 的属性。但是无法调用数组的方法,可以根据索引获取内部项的数据结构。如 arguments、获取到的 DOM 元素或 jQuery 获取到的元素。

1.[].slice.call(args)

2.Array.prototype.slice.call(args)

3.args._proto_ = Array.prototype 

4.Array.from(args)

27、http请求状态码?也就是常见的HTTP协议状态?

  • 200  请求成功,
  • 4开头的是前端(客户端)的错误
    400  错误的请求(bad request)
    404  not found 未找到 页面未响应,
    403  服务器了解客户的请求,但是拒绝处理
  • 5开头的一般是服务器的事
    500  服务器内部错误 不能发完成客户的请求
    502  服务器作为网关或者代理收到了无效的响应
    503  service unavailable 服务不可用 服务器由于维护或 者负载过重未能应答。

28、有哪些跨页面的通信方式或技术?https://juejin.im/post/6844903811232825357

对于同源页面,常见的方式包括:

  • 广播模式:Broadcast Channe / Service Worker / LocalStorage + StorageEvent
  • 共享存储模式:Shared Worker / IndexedDB / cookie
  • 口口相传模式:window.open + window.opener
  • 基于服务端:Websocket / Comet / SSE 等

而对于非同源页面,则可以通过嵌入同源 iframe 作为“桥”,将非同源页面通信转换为同源页面通信。

vue
1、vue组件间的传值问题 (除去vue传值方式其实 本地存储、window、vuex其实都可以)
2、vuex5个核心属性 以及vuex实现
3、对于MVVM框架的理解
4、vue实现双向绑定的原理

vue数据双向绑定是通过数据劫持结合发布者-订阅者模式的方式来实现的,那么vue是如何进行数据劫持的?

属性a有两个相对应的get和set方法,为什么会多出这两个方法呢?因为vue是通过Object.defineProperty()来实现数据劫持的。

Object.defineProperty( )是用来控制一个对象属性的一些特有操作,比如读写权、是否可以枚举,这里我们主要先来研究下它对应的两个描述属性get和set


5、vue路由钩子函数
6、vue内置组件有哪些
7、vue如何封装一个组件
8、vue如何减少首屏加载时间
9、请求前后拦截可以做些什么
10、vue路由传参有哪几种方式
11、keep-alive是干什么的 (应用场景、如何有条件的缓存)
12、vue初始化如何执行watch监听 以及 深度监听如何实现
13、nextTick有什么用
14、说一下computed中的getter和setter
15、v-for循环 key的作用
16、修改对象属性页面无法完成响应式怎么办 ($set)
17、vue生命周期 (注意 这里别说完就没事了 ,尽量说一下项目中常用的以及应用场景 干什么用 比如mounted是dom树渲染结束 可访问dom结构)

创建前/后: 在 beforeCreate 阶段,vue 实例的挂载元素 el 还没有。
载入前/后:在 beforeMount 阶段,vue 实例的$el 和 data 都初始化了,但还是挂载之前为虚拟的 dom 节点,
data.message 还未替换。在 mounted 阶段,vue 实例挂载完成,data.message 成功渲染。
更新前/后:当 data 变化时,会触发 beforeUpdate 和 updated 方法。
销毁前/后:在执行 destroy 方法后,对 data 的改变不会再触发周期函数,说明此时 vue 实例已经解除了
事件监听以及和 dom 的绑定,但是 dom 结构依然存在

18、vue的单向数据流你怎么理解
19、vue如何兼容ie浏览器
20、vuex中的getters是干什么的

      vuex是一个专为vue.js应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。

getters,可以认为是store的计算属性,就是在某个数据在经过一系列的变化之后,才显示在页面上,这个时候就需要用到计算属性。
21、router和route的区别

$route为当前router跳转对象里面可以获取name、path、query、params等

$router为VueRouter实例,想要导航到不同URL,则使用$router.push方法

返回上一个history也是使用$router.go方法

22、v-if和v-show的区别

v-if:当隐藏结构时该结构会直接从整个dom树中移除;

v-show:当隐藏结构时是在该结构的style中加上display:none,结构依然保留。

什么时候使用v-if,什么时候使用v-show?

当组件中某块内容只会显示或隐藏不会被再次改变显示状态,此时用v-if更加合适,例如请求后台接口通过后台数据控制某块内容是否显示或隐藏,且这个数据在当前页不会被修改;

当组件某块内容显示隐藏是可变化的,此时用v-show更加合理,例如页面中有一个toggle按钮,点击按钮来控制某块区域的显示隐藏。

为什么这么说呢?大家都知道频繁操作dom对性能影响很大,v-if如果用在有toggle按钮控制的情况下,相当于在频繁增加dom和删除dom,所以此时用v-show更加合适

如果只是要么显示要么隐藏之后不会再改变显示隐藏状态的情况,v-if更加的合理,因为如果默认就是隐藏,相当于dom一次都不用创建,如果默认是显示,v-if和v-show效果完全一样。

23、vue中你是如何解决跨域问题的
24、谈谈你对minxins混入的理解以及用法
25、v-if和v-for的优先级谁高

当 v-if 与 v-for 一起使用时,v-for 具有比 v-if 更高的优先级。

webpack (经常问到)
基本上就是问一些配置、以及你项目中所配置的一些东西

答题尽量掌握技巧,你要清楚面试官问你这个问题是为了什么,从而来举
例说明,有些问题可能是在给你挖坑,尽量不要提及自己不会的一些知识点
面试中遇到不会的问题尽量不要拖延时间,也不要说说什么以前用过但是
忘了、我觉得这个不重要 等等之类的话

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