2021年前端面试题及答案(更新中)

17 篇文章 0 订阅

http和https的基本概念

http:
超文本传输协议,是互联网上应用最为广泛的一种网络协议,是- 一个客户端和服务器端请求和应答的标准(TCP),用于从www服务器传输文本到本地浏览器的传输协议,它可以使浏览器更加高效,使网络传输减少.

https:
是以安全为目标的HTP通道,简单讲是HTTP的安全版,即HTTP 下加入SSL层,HTTPS的安全基础是SSL,因此加密的详细内容就需要SSL.
htps协议的主要作用是:
建立一个信息安全通道,来确保数组的传输,确保网站的真实性.
https的SSL加密是在传输层实现的.


http和https的区别?

http传输的数据都是未加密的,也就是明文的,网景公司设置了SSL协议来对http协议传输的数据进行加密处理,简单来说hps协议是由http和ss协议构建的可进行加密传输和身份认证的网络协议,比htp协议的安全性更高. 主要的区别如下:

1.Https协议需要ca证书,费用较高.
2.http是超文本传输协议,信息是明文传输,
3.https 则是具有安全性的ssl加密传输协议.
4.使用不同的链接方式,端口也不同,一般而言,http 协议的端口为80, https 的端口为443
5.http的连接很简单,是无状态的: HTTPS 协议是由SSL+HTTP协议构建的可进行加密传输、身份认证的网络协议,比http协议安全.


Cookie、 sessionStorage. localStrage 的区别

共同点:都是保存在浏览器端,并且是同源的

Cookie:
cookie 数据始终在同源的http请求中携带(即使不需要),即cookie在浏览器和服务器间来回传递。而ssionStorage和localStorage不会自动把数据发给服务器,仅在本地保存. cookie 数据还有路径(path) 的概念,可以限制cookie只属于某个路径下,存储的大小很小只有4K左右,(key: 可以在浏览器和服务器端来回传递,存储容量小,只有大约4K左右)
cookie的作用:保存用户登录状态。例如将用户id存储一个cookie内,这样当用户下次访问该页面时就不需要重新登录了,现在很多论坛和社区都提供这样的功能。cookie 还可以设置过期时间,当超过时间期限后,cookie 就会自动消失。因此,系统往往可以提示用户保持登录状态的时间:常见选项有一个月、三个月、一年等.跟踪用户行为.例如一个天气预报网站,能够根据用户选择的地区显示当地的天气情况.如果每次都需要选择所在地是烦琐的,当利用了cookie 后就会显得很人性化了,系统能够记住上一次访问的地区,当下次再打开该页面时,它就会自动显示上次用户所在地区的天气情况.因为-切都是在后台完成,所以这样的页面就像为某个用户所定制的一样

sessionStorage:

1.仅在当前浏览器窗口关闭前有效,页面关闭随之失效不可能持久保持,
2.session 为一个回话,当页面不同即使是同一页面打开两次,也被视为同一次回话

localStorage

始终有效,窗口或浏览器关闭也一直保存,因此用作持久数据;
localStorage 在所有同源窗口中都是共享的;cookie 也是在所有同源窗口中都是共享的. (key: 同源窗口都会共享, 并且不会失效,不管窗口或者浏览器关闭与否都会始终生效)

GET和POST的区别

  1. get参数通过url传递,post 放在request body中.
  2. get请求在url中传递的参数是有长度限制的,而post没有.
  3. get不安全,因为参数直接暴露在url中,所以不能用来传递敏感信息。
  4. get请求只能进行url编码,而post支持多种编码方式
  5. get请求会浏览器主动cache,而post支持多种编码方式.
  6. get请求参数会完整保留在浏览历史记录里,而post中的参数不会被保留.

http返回的状态码

100 Continue 继续。 客户端应继续其请求
l01 Switching Protocols 切换协议.服务器根据客户端的请求切换协议.只能切换到更高级的协议,例如,切换到HTTP的新版本协议
200 OK请求成功. 一般用于GET与POST请求
206 Partial Content部分内容. 服务器成功处理了部分GET请求
300 Muliple Choices多 种选择.请求的资源可包括多个位置,相应可返回一个资源特征与地址的列表用于用户终端(例如:浏览器)选择
301 Moved Permnanenty永久移动. 请求的资源已被永久的移动到新URI,返回信息会包括新的URI,浏览器会自动定向到新URI.今后任何新的请求都应使用新的URI代替
302 Found 临时移动。 与301类似.但资源只是临时被移动.客户端应继续使
304 Not Modified未修改. 所请求的资源未修改,服务器返回此状态码时
305使用代理。所请求的资源必须通过代理访问
400 Bad Request客 户端请求的语法错误,服务器无法理解
401 Unauthorized 请求要求用户的身份认证
402 Payment Required保留, 将来使用
403 Forbidden 拒绝请求,无权访问
404 Not Found服务器无法根据客户端的请求找到资源(网页)
408 Request Time-out服务器等待客户端发送的请求时间过长,超时
409Conflict服务器完成客户端的PUT请求是可能返回此代码,服务器处理请求时发生了冲突
410m Gone客户 端请求的资源已经不存在.
500 Intemnal Server Error服务器内部错误,无法完成请求

清除浮动的方法

使用带clear属性的空元素

在浮动元素后使用一个空元素如<div class=" clear*>,并在CSS中赋
予.clear(clearboth;)属性即可清理浮动.亦可使用<br class= ‘clear”1>或<hr class="clear’ 1>来进行清理.

使用CSS的overlow属性
给浮动元素的容器添加overflow hidden:或ovrlow:auto;可以清除浮动,另外在IE6 中还需要触发hasLayout,例如为父元素设置容器宽高或设置zoom:1.在添加overflow属性后,浮动元素又回到了容器层,把容器高度撑起,达到了 清理浮动的效果.

给浮动的元素的容器添加浮动

给浮动元素的容器也添加上浮动属性即可清除内部浮动,但是这样会使其整体浮动,影响布局,不推荐使用.

使用CSS的after伪元素
结合after伪元素(注意这不是伪类,而是伪元素,代表-个元素之后最近的元素)和Ehack,可以完美兼容当前主流的各大浏览器,这里的IEhack 指的是触发hasl ayout.给浮动元素的容器添加一一个clearfix的class,然后给这个class添加一个after伪元素实现元素末尾添加一个看不见的块元素(Block element)清理浮动.

怎么样让一个元素消失

display:none;
visibility:hidden;
opacity: 0;

盒模型

标准盒模型:
一个块的总宽度=width+margin(左右)+ padding(左右)+border(左右)

怪异盒模型:
一个块的总宽度=width+margin (左右) (既 width已经包含了padding和border值)
设置盒模型: box-sizing:border-box

定位position 相关属性

固定定位fiexd:
元素的位置相对于浏览器窗口是固定位置,即使窗口是滚动的它也不会移动。Fixed 定 位使元素的位置与文档流无关,因此不占据空间。 Fixed 定位的元素和其他元素重叠。

相对定位 relative:
如果对一个元素进行相对定位,它将出现在它所在的位置上。然后,可以通过设置垂直 或水平位置,让这个元素“相对于”它的起点进行移动。 在使用相对定位时,无论是 否进行移动,元素仍然占据原来的空间。因此,移动元素会导致它覆盖其它框。

绝对定位 absolute:
绝对定位的元素的位置相对于最近的已定位父元素,如果元素没有已定位的父元素,那 么它的位置相对于 html 。absolute 定位使元素的位置与文档流无关,因此不占据空间。 absolute 定位的元素和其他元素重叠。

粘性定位 sticky:
元素先按照普通文档流定位,然后相对于该元素在流中的 flow root(BFC)和 containing block(最近的块级祖先元素)定位。而后,元素定位表现为在跨越特定阈值前为相对定 位,之后为固定定位。 默认定位 Static: 默认值。没有定位,元素出现在正常的流中(忽略 top, bottom, left, right 或者 z-index 声 明)。 inherit: 规定应该从父元素继承 position 属性的值。

盒子垂直水平居中

1、父级元素设置 text-align:center,然后设置 line-height 和 vertical-align 使其垂直居中, 最后设置 font-size:0 消除近似居中的 bug
2、父级元素设置 display:table-cell,vertical-align:middle 达到水平垂直居中
3、采用绝对定位,原理是子绝父相,父元素设置 position:relative,子元素设置 position: absolute,然后通过 transform 或 margin 组合使用达到垂直居中效果,设置 top:50%,left: 50%,transform:translate(-50%,-50%)
4、绝对居中,原理是当 top,bottom 为 0 时,margin-top&bottom 设置 auto 的话会无限延 伸沾满空间并平分,当 left,right 为 0 时,margin-left&right 设置 auto 会无限延伸占满空 间并平分,
5、采用 flex,父元素设置 display:flex,子元素设置 margin:auto 6、视窗居中,vh 为视口单位,50vh 即是视口高度的 50/100,设置 margin:50vh auto 0, transform:translate(-50%)

css预处理器

css有那些缺点:
代码不整洁,不灵活,
不利于维护, 无法嵌套,

什么是预处理:
使用一种新的语言将Css作为目标生成文件,然后只要使用这种语言进行编码工作。预处理器通常可以实现浏览器兼容,变量,结构体等功能,代码更加简洁易于维护

sass和less的不同之处

1.Sass的安装需要安装Ruby环境,Less基于JavaScript,是需要引入Less.js来处理代码输出css到浏览器,也可以在开发环节使用Less,然后编译成css文件,直接放在项目中,有less.app、SimpleLess、CodeKit.app这样的工具,也有在线编辑地址。
2. less使用较sass简单:LESS 并没有裁剪 CSS 原有的特性,而是在现有 CSS 语法的基础上,为 CSS 加入程序式语言的特性。只要你了解 CSS 基础就可以很容易上手。
3.功能上,sass较less略强大:
①sass有变量和作用域。

a.  $variable,like php
b. #{$variable}like ruby

c.变量有全局和局部之分,并且有优先级。
②sass有函数的概念;
a.@function和@return以及函数参数(还有不定参)可以让你像js开发那样封装你想要的逻辑。
b.@mixin类似function但缺少像function的编程逻辑,更多的是提高css代码段的复用性和模块化,这个用的人也是最多的。
c.ruby提供了非常丰富的内置原生api。
③进程控制:
-条件:@if @else;
-循环遍历:@for @each @while
-继承:@extend
-引用:@import
④数据结构:
$list类型=数组;
$map类型=object;
其余的也有string、number、function等类型

JavaScript

js数据类型有哪些

JS的基本类型和引用类型有哪些呢?
基本类型(单类型):除Object。 String、Number、boolean、null、undefined。
引用类型:object。里面包含的 function、Array、Date。

Number: 数字类型,表示数据的整数和浮点数某些语言中也称为“双精值”。

String: 字符串可以有单引号、双引号表示。字符串是不可变的,一旦创建,值就不能改变 要改变某个变量保存的字符串,首先要销毁原来的字符串,然后于用另一个包含的字符串填充该变量。
Boolean: 使用最多的一个类型,有两个字面值,分别是true、false。true不一定等于1,false不一定等于0。boolean类型的字面值是区分大小写的。
undefined: 只有一个值,是undefined。没有初始化。undefined 是从 null 中派生出来的。
Null : 只有一个值,是 null。不存在的对象null是表示一个空对象指针,这也是typeof操作符检测 null 值时会返回 object 的原因
(ES6 Symbol ): Symbol 类型的对象永远不相等,即便创建的时候传入相同的值。因此,可以用解决属性名冲突的问题(适用于多少编码),做为标记。
object:对象其实就是一组数据和功能的集合。对象可以通过执行new操作符后跟要创建的对象类型的名称来创建。创建object类型的实例并为其添加属性(或)方法,就可以自定义创建对象。
Object 中包含:
其中包含了Data、function、Array等。这三种是常规用的

NaN 的数据类型是 number
数组(Array)的数据类型是 object
日期(Date)的数据类型为 object
null 的数据类型是 object
未定义变量的数据类型为 undefined

null 不存在的因素及解决方案
原因是:
1、方法不存在
2、对象不存在
3、字符串变量不存在
4、接口类型对象没初始化
解决方法:
做判断处理的时候,放在设定值的最前面

JS 判断类型

  1. typeof的语法
    typeof是一个运算符,有2种使用方式:typeof(表达式)和typeof 变量名,第一种是对表达式做运算,第二种是对变量做运算。

  2. typeof的返回值
    typeof运算符的返回类型为字符串,值包括如下几种:
    1. ‘undefined’ --未定义的变量或值
    2. ‘boolean’ --布尔类型的变量或值
    3. ‘string’ --字符串类型的变量或值
    4. ‘number’ --数字类型的变量或值
    5. ‘object’ --对象类型的变量或值,或者null
    (这个是js历史遗留问题,将null作为object类型处理)
    7. ‘function’ --函数类型的变量或值

  3. 简单的示例
    console.log(typeof a); //‘undefined’
    console.log(typeof(true)); //‘boolean’
    console.log(typeof ‘123’); //‘string’
    console.log(typeof 123); //‘number’
    console.log(typeof NaN); //‘number’
    console.log(typeof null); //‘object’

数组常用方法

join() (数组转字符串)
数组转字符串,方法只接收一个参数:即默认为逗号分隔符()

  var arr=[1,2,3,4];
	console.log(arr.join()); //1,2,3,4
	console.log(arr.join(":")); //1:2:3:4
	console.log(arr); //[1,2,3,4],原数组不变

push():方法可向数组的末尾添加一个或多个元素,并返回新的长度。

pop():方法用于删除并返回数组的最后一个元素。

var arr=[1,2,3,4];
	//push
	var push_arr=arr.push("Tom","Sun");
	console.log(arr); //[1,2,3,4,"Tom","Sun"];
	console.log(push_arr); // 6
	//pop
	var pop_arr=arr.pop();
	console.log(arr); //[1,2,3,4,"Tom"];

shift():方法用于把数组的第一个元素从其中删除,并返回第一个元素的值。

unshift():方法可向数组的开头添加一个或更多元素,并返回新的长度。

	var arr=[1,2,3,4];
	//shift
	var shift_arr=arr.shift();
	console.log(arr); // [2, 3, 4]
	console.log(shift_arr); // 1
	//unshift
	var unshift_arr=arr.unshift("Tom");
	console.log(arr); // ["Tom", 2, 3, 4]
	console.log(unshift_arr); // 4

sort()(排序)改变原数组
方法用于对数组的元素进行排序。

var arr=[1,10,5,20];
	console.log(arr.sort()); // [1, 10, 20, 5]
	console.log(arr); // [1, 100, 20, 5] (原数组改变)

reverse() (反转数组)

concat() (连接两个或多个数组)
concat() 方法用于连接两个或多个数组。该方法不会改变现有的数组,而仅仅会返回被连接数组的一个副本。在没有给 concat()方法传递参数的情况下,它只是复制当前数组并返回副本。

slice()(数组截取)
arr.slice(start , end);
start:必需。规定从何处开始选取。如果是负数,那么它规定从数组尾部开始算起的位置。也就是说,-1 指最后一个元素,-2 指倒数第二个元素,以此类推。
end:可选。规定从何处结束选取。该参数是数组片断结束处的数组下标。如果没有指定该参数,那么切分的数组包含从 start 到数组结束的所有元素。如果这个参数是负数,那么它规定的是从数组尾部开始算起的元素。
返回值: 返回一个新的数组,包含从 start 到 end (不包括该元素)的 arr 中的元素。

var arr = [1,4,6,8,12];
	var arr1 = arr.slice(1);	
	var arr2 = arr.slice(0,4);	
	var arr3 = arr.slice(1,-2);
	var arr4 = arr.slice(-5,4);
	var arr5 = arr.slice(-4,-1)
	console.log(arr1);  // [4, 6, 8, 12]
	console.log(arr2);  // [1, 4, 6, 8] 
	console.log(arr3);  // [4, 6] 
	console.log(arr4);  // [1, 4, 6, 8]
	console.log(arr5);  // [4, 6, 8]
	console.log(arr);  // [1, 4, 6, 8, 12] (原数组未改变) 

splice() (数组更新)

splice() 方法向/从数组中添加/删除项目,然后返回被删除的项目。(该方法会改变原始数组)
arr.splice(index , howmany , item1,…,itemX)
index:必需。整数,规定添加/删除项目的位置,使用负数可从数组结尾处规定位置。
howmany:必需。要删除的项目数量。如果设置为 0,则不会删除项目。
item1, …, itemX:可选。向数组添加的新项目。
返回值: 含有被删除的元素的数组,若没有删除元素则返回一个空数组

var arr = ["张三","李四","王五","小明","小红"];
	/**************删除"王五"****************/
	var arrReplace1 = arr.splice(2,1);	
	console.log(arrReplace1);  // ["王五"] 
	console.log(arr);  // ["张三","李四","小明","小红"](原数组改变)
	//删除多个
	var arrReplace2 = arr.splice(1,2);	
	console.log(arrReplace2);  //  ["李四", "小明"] 
	console.log(arr);  // ["张三", "小红"]

indexOf()和 lastIndexOf()
两个方法都返回要查找的项在数组中首次出现的位置,在没找到的情况下返回-1
返回值:为下表
indexOf()
array.indexOf(item,start) (从数组的开头(位置 0)开始向后查找)
item: 必须。查找的元素。
start:可选的整数参数。规定在数组中开始检索的位置。如省略该参数,则将从array[0]开始检索。
备注:不存在查找属性返回-1
缺点:
一是不够语义化,其定义是:找到参数值的第一次出现的位置,找不到时会返回 -1 ,所以还需要比较是否等于 -1,表达起来不够方便;
二是,其内部使用的是严格等式运算符(===)进行判断,会导致对NaN的误判(因为NaN === NaN会返回false,如果数组中存在该元素,则无法找到);

lastIndexOf()
array.lastIndexOf(item,start) (从数组的末尾开始向前查找)
item: 必须。查找的元素。
start:可选的整数参数。规定在数组中开始检索的位置。如省略该参数,则将从 array[array.length-1]开始检索。

var arr = [1,4,7,10,7,18,7,26];
	console.log(arr.indexOf(7));        // 2
	console.log(arr.indexOf(5));        // -1	

数组迭代方法

forEach():对数组进行遍历循环,这个方法没有返回值。

//这几个方法语法都一样,都不会改变原数组。
jquery()也有相应的方法each()
语法:
array.forEach(function(currentValue , index , arr)
{//do something}, thisValue)
currentValue : 必需。当前元素
index: 可选。当前元素的索引值。
arr :  可选。当前元素所属的数组对象。
thisValue: 可选。传递给函数的值一般用 "this" 值。
如果这个参数为空, "undefined" 会传递给 "this"var Arr = [1,8,4,2];
Arr.forEach(function(currentValue, index, arr){
	console.log(index+"--"+currentValue+"--"+(arr === Arr));		
})

map():
必须。函数,数组中的每个元素都会执行这个函数
map() 方法返回一个新数组,数组中的元素为原始数组元素调用函数处理后的值。
map() 方法按照原始数组元素顺序依次处理元素。
注意: map() 不会对空数组进行检测。
注意: map() 不会改变原始数组。

语法:array.map(function(currentValue , index , arr)
{//do something}, thisValue)  
    var arr = [1,4,8,10];
    var arr2 = arr.map(function(currentValue){
        return currentValue*currentValue;
    });
    console.log(arr2);  // [1, 16, 64, 100]

filter(callback)返回符合callback函数的元素数组
filter(): “过滤”功能,
创建一个新数组, 新数组中的元素是通过检查指定数组中符合条件的所有元素
jquery中有个 grep()方法也用于数组元素过滤筛选
注意: filter() 不会对空数组进行检测。
注意: filter() 不会改变原始数组。
备注: 函数支持弱等于(==)

 var arr = [1,4,6,8,10];
    var result1 = arr.filter(function(currentValue){
        return currentValue>5;
    });
    console.log(result1);  // [6, 8, 10]
  

every():
判断数组中每一项都是否满足条件,只有所有项都满足条件,才会返回true。
方法用于检测数组所有元素是否都符合指定条件(通过函数提供)
方法使用指定函数检测数组中的所有元素
如果数组中检测到有一个元素不满足,则整个表达式返回 false ,且剩余的元素不会再进行检测。
如果所有元素都满足条件,则返回 true。

array.every(function(currentValue,index,arr), thisValue)
参数	描述
currentValue	必须。当前元素的值
index	可选。当前元素的索引值
arr	可选。当前元素属于的数组对象
thisValue	可选。对象作为该执行回调时使用,传递给函数,
用作 "this" 的值。
如果省略了 thisValue ,"this" 的值为 "undefined"
	var arr = [1,4,6,8,10];
	var result1 = arr.every(function(currentValue){
	    return currentValue< 12;
	});
	console.log(result1);  // true
	var result2 = arr.every(function(currentValue){
	    return currentValue> 1;
	});
	console.log(result2);  // false

some():
some() 方法用于检测数组中的元素是否满足指定条件(函数提供)。
some() 方法会依次执行数组的每个元素:
如果有一个元素满足条件,则表达式返回true , 剩余的元素不会再执行检测。
如果没有满足条件的元素,则返回false。

array.some(function(currentValue,index,arr),thisValue)
参数	描述
currentValue	必须。当前元素的值
index	可选。当前元素的索引值
arr	可选。当前元素属于的数组对象

    var arr = [1,4,6,8,10];
	var result1 = arr.some(function(currentValue){
	    return currentValue> 10;
	});
	console.log(result1);  // false
	var result2 = arr.some(function(currentValue){
	    return currentValue> 5;
	});
	console.log(result2);  // true

reduce
reduceRight()
则从数组的最后一项开始,向前遍历到第一项方法与reduce相同

reduce() 方法接收一个函数作为累加器,数组中的每个值(从左到右)开始缩减,最终计算为一个值。
reduce() 可以作为一个高阶函数,用于函数的 compose。
array.reduce(function(total, currentValue, currentIndex, arr), initialValue)

语法
array.reduce(function(total, cur, currentIndex, arr),
 initialValue)

参数	描述
total	        必需。初始值, 或者计算结束后的返回值。
cur	            必需。当前元素
currentIndex	可选。当前元素的索引
arr	            可选。当前元素所属的数组对象。
initialValue	可选。传递给函数的初始值

    var arr = [1,2,3,4,5];
	var result1 = arr.reduce(function(total,cur,index,arr){	
		console.log("total:"+total+",cur:"+cur+",index:"+index);
	    return total+cur;
	});
	console.log("结果:"+result1);

ES6新增数组方法

Array.from()
Array.from()方法的作用是将类数组或可迭代对象转换为数组

Array.from()
作用:将类数组或可迭代对象转换为数组
参数:必带的arrayLike(想要转换成数组的伪数组对象或可迭代对象)
返回值:新的数组实例
是否影响原结构:不影响

//4、从类数组对象(arguments)生成数组
function f() {
  console.log(arguments);
  console.log(Array.from(arguments)); // [ 1, 2, 3 ]
}
f(1, 2, 3);

Array.of()
参数:元素可以是任意多个
作用:创建一个具有可变数量参数的新数组实例,
而不考虑参数的数量或类型
数量为0返回空数组

let arr1 = Array.of(1,2,3);	
	let arr2 = Array.of([1,2,3]);
	let arr3 = Array.of(undefined);
	let arr4 = Array.of();
	console.log(arr1); // [1, 2, 3]
	console.log(arr2); // [[1, 2, 3]]
	console.log(arr3); // [undefined]
	console.log(arr4); // []

find()
遍历数组,当数组中的元素在测试条件时返回 true 时, 之后的值不会再调用执行函数。如果没有符合条件的元素返回 undefined。
备注 find() 对于空数组,函数是不会执行的。find() 并没有改变数组的原始值。
返回的结果: 为查找到的元素:

alue:当前的数组元素
index:当前索引值。
arr:被查找的数组。
按索引值查找

let myArr=[1,2,3,4,5,6];
var v=myArr.find((value,index,arr)=>{
    return index==4
});
console.log(v);// 5
根据对象id取出对象属性
let Arr = [
		{id:1,name:"张三"},
		{id:2,name:"李四"}		
	];
	let obj = Arr.find((currentValue,index,arr)=>{			
		return currentValue.id===2;
	});
	console.log(obj.name); //李四

findIndex
indIndex和find差不多,不过默认返回的是索引,
如果没有符合条件的元素返回 -1

fill()

fill()方法用一个固定值覆盖一个数组中从的全部元素。不包括终止索引。

语法:array.fill(value,  start,  end)
value:必需。填充的值。
start:可选。开始填充位置。如果这个参数是负数,那么它规定的是从数组尾部开始算起。
end:可选。停止填充位置 (默认为 array.length)。如果这个参数是负数,那么它规定的是从数组尾部开始算起。

  var arr = [1,2,3,4,5,6];
   arr.fill(0);  // [0, 0, 0, 0, 0, 0]
   arr.fill(0,1);  // [1, 0, 0, 0, 0, 0]

遍历数组方法 keys()、values()、entries()
这三个方法都是返回一个遍历器对象,可用for…of循环遍历,唯一区别:keys()是对键名的遍历、values()对键值的遍历、entries()是对键值对的遍历。

keys()
	let arr = ["a","b","c","d"];
	for(let i of arr.keys()){
		console.log(i);
	}
    //打印:
    // 0
    // 1
    // 2
    // 3
values()
	let arr = ["a","b","c","d"];
	for(let i of arr.values()){
		console.log(i);
	}
    //打印:
    // a
    // b
    // c
    // d
entries()
    let arr = ["a","b","c","d"];
    for(let i of arr.entries()){
        console.log(i);
    }
    //打印:
    // [0, "a"]
    // [1, "b"]
    // [2, "c"]
    // [3, "d"]
    for(let [idx,item] of arr.entries()){
        console.log(idx+":"+item);
    }
    //打印:
    // 0:a
    // 1:b
    // 2:c
    // 3:d

includes()
方法用来判断一个数组是否包含一个指定的值,如果是返回 true,否则false。
返回值:个布尔值 Boolean

arr.includes(searchElement, fromIndex)
参数	描述
searchElement	必须。需要查找的元素值。
fromIndex	可选。从该索引处开始查找 searchElement。
如果为负值,则按升序从 array.length + fromIndex 的索引开始搜索。
默认为 0let arr = ["a","b","c","d"];
	let result1 = arr.includes("b");
	let result2 = arr.includes("b",2);
	let result3 = arr.includes("b",-1);
	let result4 = arr.includes("b",-3);
	console.log(result1);  // true
	console.log(result2);  // false
	console.log(result3);  // flase
	console.log(result4);  // true

copyWithin
方法用于从数组的指定位置拷贝元素到数组的另一个指定位置中,会覆盖原有成员

array.copyWithin(target ,  start ,  end)
target : 必需。从该位置开始替换数据。
start :  可选。从该位置开始读取数据,默认为 0 。如果为负值,表示倒数。
end:    可选。到该位置前停止读取数据,默认等于数组长度。
如果为负值,表示倒数。

let arr = [1,2,3,4,5,6];
	let result1 = [1,2,3,4,5,6].copyWithin(0);
	let result2 = [1,2,3,4,5,6].copyWithin(0,1);
	let result3 = [1,2,3,4,5,6].copyWithin(1,3,5);
	let result4 = [1,2,3,4,5,6].copyWithin(1,2,-1);
	let result5 = [1,2,3,4,5,6].copyWithin(1,-4,6);
	console.log(result1);  // [1, 2, 3, 4, 5, 6]
	console.log(result2);  // [2, 3, 4, 5, 6, 6]
	console.log(result3);  // [1, 4, 5, 4, 5, 6]
	console.log(result4);  // [1, 3, 4, 5, 5, 6]
	console.log(result5);  // [1, 3, 4, 5, 6, 6]

字符串转为数组

**toString()** 数组中 toString() 方法能够把每个元素转换为字符串,然后以逗号连接输出显示。 纯文本复制
var a = [1,2,3,4,5,6,7,8,9,0];  //定义数组
var s = a.toString();  //把数组转换为字符串
console.log(s);  //返回字符串“1,2,3,4,5,6,7,8,9,0”
toString()是将数组的每个元素都转换为字符串,然后拼接起来
多维数组也可以使用
var a = [1,[2,3],[4,5]],[6,[7,[8,9],0]]];  //定义多维数组
var s = a.toString();  //把数组转换为字符串
console.log(S);  //返回字符串“1,2,3,4,5,6,7,8,9,0”

toLocalString()

var a = [1,2,3,4,5];  //定义数组
var s = a.toLocalString();  //把数组转换为本地字符串
console.log(s);  //返回字符串“1,2,3,4,5,6,7,8,9,0”

join()
join() 方法可以把数组转换为字符串,可使用指定分隔符

var a = [1,2,3,4,5];  //定义数组
var s = a.join("==");  //指定分隔符
console.log(s);  //返回字符串“1==2==3==4==5”

split() 方法是 String 对象方法 将字符串转为数组

toString()与toLocaleString()的区别

toString() 方法可把一个逻辑值转换为字符串,并返回结果。

toLocaleString()把数组转换为本地字符串。
在这里插入图片描述

检测数组类型的方法

instanceof 操作符
instanceof 就是判断一个实例是否属于某种类型

let arr=["2',"8',"9'];
要检测的对象 instanceof   该对象的类型
console. log ( arr instanceof Array)
true

let test =1
console. log( test instanceof Array)
false

constructor 构造函数

对象的 constructor 属性 可以返回创建该对象的函数, 也就是 构造函数
除了一些特殊对象 其他对象都具备 构造器,
特殊对象:arguments、Enumerator、Error、Global、Math、RegExp、Regular Expression等
对象中的 constructor属性 指向的函数本身,一般都有内置对象均具有 constructor 。
如:Array、Boolean、Date、Function、Number、Object、String等。

let arr=['8',"2"]
console. log (arr.constructor == Array)
true
let arr1 123:
console. log(arrl.constructor == Array)
false

Array.isArray( ) 检验值是否为数组
Array 类型的一个静态方法,使用它可以判断一个值是否为数组

let demo =[!]:
console. log(Array.isArray(demo))
true
. undefined
let demo1 123;
console. log(Array.isArray(demo1))
false

检测对象类型的方法

按内容比较对象的明显方法是读取属性并手动比较它们。

自定义一个方法,将所比较的对象传入比较其属性
function isHero(ob, ob2){
return ob.name ==ob2.name
}
let herol={name: Batman
}
const hero2={
name: Batman
}
const hero={
name: aaaa
}
isHero(herol, hero2): //=>true
isHero(herol, hero); //= false

在对对象进行浅层相等性检查时,获得Object.keys()两个对象的属性列表,然后检查属性值是否相等。

//在函数内部,keys1并且keys2是包含相应的属性名称数组object1和object2
//for循环遍历的密钥,并且每个属性的比较object1和object2是否相等object1[key] !== object2[key]。
function shallow Equal(object1, object 2){
    const keysl =Object keys(object1);
    const keys2=Object keys(object2):
    
    if(keys1 length !== keys2. length){return false}
    
    for(let key of keys1){
      if(objectI[key]! = object2[key]){
       return false.
   }
   
  return true
}
const herol ={
   name: Batman
   real Name:"Bruce Wayne
}
const hero2={
   name:Batman
    realName: Bruce Wayne
}
const hero3={
   name: Joker
}

shallow Equal(herol, hero2)://=>true
shallow Equal(herol, hero)://=> false

什么闭包

闭包就是能够读取其他函数内部变量的函数,或者子函数在外调用, 子函数所在的父函数的作用域不会被释放。

什么是事件流

事件流描述的是从页面中接收事件的顺序
事件捕获阶段
处于目标阶段
事件冒泡阶段

事件委托

事件委托指的是,不在事件的当前元素上设置监听函数,而是在其父 元素上设置监听函数,通过事件冒泡,父元素可以监听到子元素上事件的触发,通过判 断事件发生元素 DOM 的类型,来做出不同的响应。 举例:最经典的就是 ul 和 li 标签的事件监听,比如我们在添加事件时候,采用事件委 托机制,不会在 li 标签上直接添加,而是在 ul 父元素上添加。
好处:比较合适动态元素的绑定,新添加的子元素也会有监听函数,也可以有事件触发 机制。

图片预加载懒加载

预加载:提前加载图片,当用户需要查看时可直接从本地缓存中渲染。
懒加载:懒加载的主要目的是作为服务器前端的优化,减少请求数或延迟请求数。
两种技术的本质:两者的行为是相反的,一个是提前加载,一个是迟缓甚至不加载。 懒加载对服务器前端有一定的缓解压力作用,预加载则会增加服务器前端压力。

mouseover 和 mouseenter 的区别

mouseover:当鼠标移入元素或其子元素都会触发事件,所以有一个重复触发,冒泡的过程。
对应的移除事件是 mouseout mouseenter:当鼠标移除元素本身(不包含元素的子元素)会触发事件,也就是不会冒 泡,对应的移除事件是mouseleave

改变函数内部 this 指针的指向函数(bind,apply,call 的区别)

通过 apply 和 call 改变函数的 this 指向,他们两个函数的第一个参数都是一样的表示要改变指向的那个对象,第二个参数,apply 是数组,而 call 则是 arg1,arg2...这种形式。通 过 bind 改变 this 作用域会返回一个新的函数,这个函数不会马上执行。

JS 的各种位置

clientHeight:表示的是可视区域的高度,不包含 border 和滚动条
offsetHeight:表示可视区域的高度,包含了 border 和滚动条 scrollHeight:表示了所有区域的高度,包含了因为滚动被隐藏的部分。
clientTop:表示边框 border 的厚度,在未指定的情况下一般为 0 scrollTop:滚动后被隐藏的高度,获取对象相对于由 offsetParent 属性指定的父坐标(css 定位的元素或 body 元素)距离顶端的高度

JS 拖拽功能的实现

首先是三个事件,分别是 mousedown,mousemove,mouseup 当鼠标点击按下的时候,需要一个 tag 标识此时已经按下,可以执行 mousemove 里面的 具体方法。 clientX,clientY 标识的是鼠标的坐标,分别标识横坐标和纵坐标,并且我们用 offsetX 和 offsetY 来表示元素的元素的初始坐标,
移动的举例应该是:
元素y = 现在鼠标y - 原来鼠标y + 原来元素y

异步加载 JS 的方法

同步加载,又称阻塞模式,会阻止浏览器的后续处理,停止后续的解析,只有当前程序加载完成,才能进行下一步操作。所以默认同步执行才是安全的。但这样如果js中有输出document内容、修改dom、重定向等行为,就会造成页面堵塞。所以一般建议把<script>标签放在<body>结尾处,这样尽可能减少页面阻塞。

异步加载又叫非阻塞加载,浏览器在下载执行js的同时,还会继续进行后续页面的处理

异步加载方法:

需要引入jquery
兼容所有浏览器
$(document).ready(function() {
    alert("加载完成!");
});
方案二、<script>标签的async="async"属性
async属性是HTML5新增属性,需要Chrome、FireFox、IE9+浏览器支持
async属性规定一旦脚本可用,则会异步执行
async属性仅适用于外部脚本
此方法不能保证脚本按顺序执行
<script type="text/javascript" src="xxx.js" async="async"></script>
方案三、<script>标签的defer="defer"属性
defer属性规定是否对脚本执行进行延迟,直到页面加载为止
如果脚本不会改变文档的内容,可将defer属性加入到<script>标签中,
以便加快处理文档的速度
兼容所有浏览器
此方法可以确保所有设置了defer属性的脚本按顺序执行
方案四、动态创建<script>标签
兼容所有浏览器

(function(){
    var script = document.createElement('script');
    script.type = 'text/javascript';
    script.src = "http://code.jquery.com/jquery-1.7.2.min.js";
    var tmp = document.getElementsByTagName('script')[0];
    tmp.parentNode.insertBefore(script, tmp);
})();

前端优化
使用内容发布网络(CDN)
添加本地缓存
压缩资源文件
将 CSS 样式表放在顶部,
把 javascript 放在底部(浏览器的运行机制决定)
避免使用 CSS 表达式
减少 DNS 查询
使用外部 javascript 和 CSS 避免重定向
图片 lazyLoad

浏览器兼容

1、不同浏览器的标签默认的外补丁( margin )和内补丁(padding)不同
解决方案: css 里增加通配符 * { margin: 0; padding: 0; }
2、IE6双边距问题;在 IE6中设置了float , 同时又设置margin , 就会出现边距问题
解决方案:设置display:inline;
3、当标签的高度设置小于10px,在IE6、IE7中会超出自己设置的高度
解决方案:超出高度的标签设置overflow:hidden,或者设置line-height的值小于你的设置高度
4、图片默认有间距
解决方案:使用float 为img 布局
5、IE9一下浏览器不能使用opacity
解决方案:opacity: 0.5;filter: alpha(opacity = 50);filter: progid:DXImageTransform.Microsoft.Alpha(style = 0, opacity = 50);
6、边距重叠问题;当相邻两个元素都设置了margin 边距时,margin 将取最大值,舍弃最小值;
解决方案:
为了不让边距重叠,可以给子元素增加一个父级元素,并设置父级元素为 overflow:hidden;
7、cursor:hand 显示手型在safari 上不支持
解决方案:统一使用 cursor:pointer
8、两个块级元素,父元素设置了overflow:auto;子元素设置了position:relative ;且高度大于父元素,在IE6、IE7会被隐藏而不是溢出;
解决方案:父级元素设置position:relative
9.css3新属性,加浏览器前缀兼容早期浏览器
-moz- /* 火狐浏览器 /
-webkit- / Safari, 谷歌浏览器等使用Webkit引擎的浏览器 /
-o- / Opera浏览器(早期) /
-ms- / IE */
10.标签最低高度设置min-height不兼容
 解决方案:要设置一个标签的最小高度200px,需要进行的设置为:{min-height:200px; height:auto !ImportAnt; height:200px; overflow:visible;}

  • 3
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
很抱歉,我无法提供完整的2024前端面试题答案,因为这些问题是根据具体公司和岗位需求而定的,而且在2024之前还有很长的时间,技术可能会有所变化。但是我可以给你提供一些常见的前端面试题答案作为参考: 1. 什么是盒模型?盒模型有哪些属性? 答:盒模型是指在网页,每个元素都被看作是一个矩形的盒子,包括内容区域、内边距、边框和外边距。盒模型的属性有width、height、padding、border和margin。 2. 请解释一下CSS选择器的优先级。 答:CSS选择器的优先级是用来确定当多个规则应用于同一个元素时,哪个规则将会被应用。优先级从高到低依次为:!important > 内联样式 > ID选择器 > 类选择器/属性选择器/伪类选择器 > 元素选择器/伪元素选择器。 3. 请解释一下什么是闭包,并举一个例子。 答:闭包是指函数可以访问其词法作用域以外的变量。一个简单的闭包例子是: ``` function outer() { var x = 10; function inner() { console.log(x); } return inner; } var closure = outer(); closure(); // 输出10 ``` 4. 请解释一下什么是跨域,以及如何解决跨域问题。 答:跨域是指在浏览器,一个域下的网页获取另一个域下的资源时遇到的限制。常见的解决跨域问题的方法有:JSONP、CORS、代理服务器等。 5. 请解释一下什么是响应式设计。 答:响应式设计是指网页能够根据不同设备的屏幕尺寸和辨率进行自适应布局和显示,以提供更好的用户体验。常见的响应式设计方法有使用媒体查询、弹性布局和流式布局等。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小四是个处女座

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值