天天看点

前端可能问到的面试题(ts,js,css,es6)

1.void,null,undefined,never,NaN

void:无返回值,只能赋值undefined和null

null:空值,表示不存在

undefined:未定义,声明了但没有赋值,对象没有赋值的属性,对象没有返回值

never:永不存在的值的类型,是

抛出异常或根本没有返回值的函数表达式

的返回值类型

NaN:和任何值都不相等,包括自身

2.const和readonly

const:修饰的常量是静态属性。声明时必须赋值,赋值后不能再改变,实际上是变量至指向的内存地址所保存的数据不改动,对于简单类型,值就保存在变量指向的内存地址。对于

复合类型的数据(引用类型)

,const只能保证这个指针是固定的,至于指针指向的数据结构是否可变就不能控制。

readonly :修饰的常量是动态属性(值在运行的时候获得)。可以在声明或构造函数中初始化

3.接口和泛型

接口:定义了要遵循的类的语法,实现接口的类必须实现它的所有成员。不同类之间公有的属性和方法可以抽象为一个接口

泛型:解决类,接口,方法的复用性(

传入什么类型就返回什么类型

),以及对不特定数据类型的支持

4.匿名函数和箭头函数

匿名函数:声明是没有任何命名标识符的函数,在运行时动态声明的,可以接受输入和返回输出,在初始创建之后通常是不可访问的

let fun=function(x:number,y:number):number{
	return x+y;
}
           

箭头函数:相当于匿名函数并且简化了函数的定义。没有prototype原型,所有箭头函数本身没有this,this在箭头函数中已经按照词法作用域绑定了,this指向是固定的。没有构造函数

箭头函数的this指向该函数所在的作用域指向的对象

5.findindex(),indexof(),forEach()

findindex()对于空数组不执行,也不使适用于字符串。范围更广,可以根据不同条件进行查询。返回的是符合查询条件的第一个值的

索引

.

let arr = [1, 1, 2, 2, 8, 8,5,4]
function check(a) {
    return a>1
}
let result = arr.findIndex(check)
console.log(result)  //2
           

indexof()返回某个指定的字符串值在字符串中首次出现的位置。空数组和字符串都会执行。

forEach() 对于空数组不执行,用于调用数组的每个元素,并将元素传递给回调函数。

示例代码

6.浏览器重定向页面,浏览器打开新页面

重定向页面

window.location.href="https://www.baidu.com/"
window.location.replace("https://www.baidu.com/")
           

打开新页面,窗口

7.splice()与slice()

splice(2,7) 表示从索引2开始的位置,截取7个长度,

会返回截取后的数据

slice(2,7) 表示从索引2开始的位置,截取到6索引的位置(不包含7),

不会改变原数组

8.promise

promise:是一个构造函数,可以实例化promise实例。有两个函数resolve(成功时的回调函数)和reject(失败后的回调函数)。在promise的构造函数的prototype属性上有then()方法。

9.px,em,rem

px:像素px是相对于显示器屏幕分辨率而言的。缺点没有弹性,IE可能不兼容

em:参考物是父元素的font-size,具有继承的特点。相对于当前对象内文本的字体尺寸。如当前对行内文本的字体尺寸未被人为设置,则相对于浏览器的默认字体尺寸。

rem:rem是相对于根元素html, 不会被它的父元素影响

10.css选择器

标签选择器div 类选择器. id选择器# 子类选择器> 兄弟选择器~ 全局选择器* 相邻选择器+ 包含选择器 伪类选择器(:hover nth-child(n):)

伪类(before,after)与伪类选择器根本区别:是否创建了新元素

11.position有哪些属性

relative:相对于原来位置移动,元素设置此属性之后仍然处在文档流中,不影响其他元素的布局

absolute:元素会脱离文档流,如果设置偏移量,会影响其他元素的位置定位。绝对定位是相对于元素最近的已定位的祖先元素(即是设置了绝对定位或者相对定位的祖先元素)。如果元素没有已定位的祖先元素,那么它的位置则是相对于最初的包含块(body)

fixed:相对于浏览器窗口,生成固定定位

inherit:继承父元素的position 属性的值

static:默认值。没有定位,元素出现在正常的流中

sticky:粘性定位,该定位基于用户滚动的位置。

12.垂直水平居中

<body>
    <div id="aaa">
        <div id="bbb"></div>
    </div>
</body>
           

方法一 相对绝对定位

body{
        margin: 0px;
        padding: 0px;
    }
    #aaa{
        position: relative;
        width: 500px;
        height: 500px;
        background: red;
    }
    #bbb{
        position:absolute;
        width: 300px;
        height: 300px;
        background: pink;
        margin: auto;
        left: 0;
        right: 0;
        top: 0;
        bottom: 0;
    }
           

方法2 flex布局

body {
      margin: 0px;
      padding: 0px;
    }
    #aaa {
      display: flex;
      width: 500px;
      height: 500px;
      justify-content: center;
      align-items: center;
      background-color: red;
    }
    #bbb {
      width: 300px;
      height: 300px;
      background-color: pink;
    }
           

13.清除浮动

方法一:添加额外标签,并在标签中使用clear:both (不推荐)

方法二:添加伪类元素(::after),设置clear:both。注意必须块级元素且IE8以上

14.行内元素与块级元素

块级元素:独占一行,默认情况下,其宽度自动填满其父元素宽度

块级元素可以设置width,height,margin,padding

行内元素:不会独占一行,行内元素设置width,height属性无效,它的长度高度主要根据内容决定。行内元素的margin和padding属性

水平方向有效果,垂直方向没有效果

15.js与ts的区别

ts是js的超集。js是脚本语言,ts是面向对象编程语言。ts支持可选参数,静态类型,接口,js不支持。ts在编译时就能报错,js运行时才暴报错。ts是强类型语言,可以明确知道参数类型。

16.axios,ajax,fetch

axios 基于promise用于浏览器和node.js的http客户端。是对ajax的封装,安全性更高。有then链,可以异步编程

function Callback<T>(promise: Promise<T>) {
    return promise
        .then((data) => { data })
        .catch((err) => { err })
}

function test() {
    return Callback(axios.get(""))
}
           

fetch只对网络请求报错,对400,500都当做成功的请求,需要封装去处理,是原生js,没有使用XMLHttpRequest对象

ajax底层使用XMLHttpRequest,

Ajax引擎在客户端运行,特点是实现局部刷新,支持异步请求的技术。不支持浏览器back,暴露了与服务器交互的细节

XmlHttpRequest可以在使用JavaScript向服务器提出请求并处理响应,而不阻塞用户。通过XMLHttpRequest对象,Web开发人员可以在页面加载以后进行页面的局部更新。

$.ajax({
   type: 'POST',
   url: url,
   data: data,
   dataType: dataType,
   success: function () {},
   error: function () {}
});
           

17.http状态码

2xx:服务器成功处理请求

例如:200 (成功)表示客户端发送的请求在服务器被正常的处理了。

3xx:状态码用于重定向

例如:301 永久性重定向,请求的资源被分配了新的URI,以后都使用这个。

302 临时性重定向,请求的资源被分配了新的URI,本次使用这个。

4xx:请求错误,客户端或许有错误

例如:404 服务器找不到资源 403 请求的资源访问被拒绝

5xx:服务器错误

例如:500 服务器执行请求时发送异常 503 服务器暂时无法处理请求

18.a标签的href和target属性

href属性用于指定超链接目标的url

target属性规定在何处打开链接文档

_blank 在新窗口打开链接

_self 在当前窗口打开链接(默认)

_top 在整个窗口中打开链接

_parent 在父框架集中打开链接

alt属性规定在图像无法显示时的替代文本

title属性规定的是在鼠标以上元素时显示的文本

19.for in 与 for of

for in 适合遍历对象,数组,通常用来遍历对象的键名,原型链上所有属性都会呗访问,用hasOwnProperty()解决

for of (es6)适合遍历树,数组,数组对象,字符串等,通常用来遍历键值

20.for循环与setTimeout()

https://www.jb51.net/article/122489.htm

21.网站的登录状态是如何保存的,完整的登录流程是什么?

通过cookie保存登录状态。cookie存储token,每次请求到后端服务器都会带上token,从而验证用户是否登录。

1.客户端请求后台登录接口。

2.后台验证通过后,将用户的登录状态保存至cookie并写入客户端。

3.客户端再次登录网站,请求login接口时,后台直接从客户端获取到该用户写入cookie的登录状态。

4.通过对该状态的验证,确认用户是否需要再次登录。

5.如cookie过期,则跳转至登录页;如未过期,则直接显示为已登录状态。

22.DOCTYPE作用

声明位于文档中最前面的位置,处于标签之前。可以告知浏览器文档使用何种规范解析页面(html,xhtml)

23.call,apply,bind

let a=[1,2,3,4,5]
console.log(Math.Max,call(null,2,3,4,5,6)) //6
console.log(Math.Max,apply(null,[2,3,4,5,6])) //6
let b=Math.Max,bind(null,2,3,4,5,6)
b() //6
           

call和apply直接执行,bind事先将方法的this改为我们想要的结果,需要时再调用执行。apply的第二个参数是以数组形式传入的。call和bind以列表参数传递。

23.src,href

href是元素或文档与指定资源联通,需要的时候再引用

src是下载后嵌入构成文档直接内容

24. get post

get:长度限制为2k,参数在url可见,速度更快

post:没有长度限制,参数写在请求头里面,安全性更高,速度不如get(因为在第三次握手时,会发送post请求头,服务器才会返回100 continue ,客户端此时才发送数据。而get在第三次握手时就已经携带了数据)

25.三次握手

why:为了保证可靠的数据传输,防止无效的请求又发送到服务器。

ACK=1 确认号有效

SYN=1 请求建立连接

seq 序列号

ack 期望下一次接收到的序列号

前端可能问到的面试题(ts,js,css,es6)

26.jsonp跨域

客户端通过script标签的src属性发送请求,并且定义一个回调函数。服务器端响应请求后会传入参数动态执行回调函数,就实现了跨域。因为是script标签,所以返回的数据会直接当作js语言执行就会产生错误,所以需要回调函数的存在,关键是服务器返回的数据外层需要需要包裹一层函数

react 使用代理中间件 http-proxy-middleware实现跨域请求

const proxy = require('http-proxy-middleware')
const { createProxyMiddleware } = require('http-proxy-middleware');
module.exports = function (app) {

    app.use(createProxyMiddleware('/api',{
        target:'http://localhost:3300',
        changeOrigin: true
    }))

};
           

27.xss,CSRF攻击

xss:跨站脚本攻击,利用网站对用户输入没有进行限制或过滤,从而在页面中嵌入某些代码,当别的用户访问到该网页时,会执行对应的代码,从而使得攻击者可以获取。

防御:设置Cookie的属性为Http only,这样js就无法获取Cookie值

CSRF攻击:跨域请求伪造,

防御:使用随机token或验证码

28.浏览器输入url到渲染的过程

1.首先是域名解析,解析到对应的ip地址

2.三次握手,请求建立连接

3.发送http请求,服务器响应请求,浏览器获取html源码

4.解析html并且构建DOM树

5.解析css生成css对象模型

6.dom树和css附着在一起呈现reader tree(重排和重绘)

7.浏览器计算节点的位置和样式进行布局

29.重排reflow和重绘repaint

重排:元素的规模,位置和隐藏等改变时,都会引起回流。

引起重排的条件:首次渲染,删除或增加dom元素,元素位置的改变,尺寸的改变,窗口尺寸的改变,读取某些元素的值。一定会引起重绘。

重绘:元素的外观改变触发的浏览器行为,浏览器会根据元素的新属性重新绘制,呈现新的外观。如:color

优化:

1.合并多次dom的修改

2.直接改变元素的类名,切换类名

3.经常进行重排的元素设置position:absolute和fixed ,脱离文档流,不会影响到其他元素

4.避免使用table布局,一个小改动会引起整个table重新布局

5.经常访问元素属性的操作时,将属性赋给局部变量进行计算。

30.new一个对象的过程

其实是一种继承的方式, 通过new,实例与构造函数通过原型链连接了起来出来,所以实例能访问到构造函数的属性。改变了构造函数的this指向

ps:

每个对象的__proto__属性都指向原型对象

每个构造函数都有prototype原型对象

prototype原型对象里都有constructor指向它的构造函数

31.盒子模型

所有的html元素都可以看作为盒模型,即content+padding+border+margin

1.标准模型:box-sizing:content-box

内容大小(宽高):content的大小,即width和height

设置padding时,content大小不变,整体变大

2.IE模型:box-sizing:border-box

内容大小:content(width,height)+padding+border

因为是包括padding的,所以设置padding时,元素会被挤压,整体不变

32.什么是flex布局

弹性布局,任何元素都可以指定为flex,随着网页的大小自适应布局。采用flex布局的元素称为容器,子元素称为项目。设置了flex之后,float,clear等属性失效。

flex(flex-grow、flex-shrink、flex-basis):

flex-grow定义项目的放大比例,默认为0,即如果存在剩余空间,也不放大

flex-shrink 定义了项目的缩小比例,默认为1,即如果空间不足,该项目将缩小

flex-basis给上面两个属性分配多余空间之前, 计算项目是否有多余空间, 默认值为 auto, 即项目本身的大小

flex:auto代表 1 1 auto

flex:1代表 1 1 0

33.BFC

块级上下文,独立的渲染区域。区域内部与外部无关。BFC中的所有子元素的左外边都会与父块的左边接触。

作用:

1.防止被浮动的元素挡住

2.解决margin塌陷的问题。因为同一BFC的两个box之间的margin以大的为准

3.自适应两栏布局

4.清除浮动(BFC计算高度时会包括浮动的高度,会清除内部子元素浮动的影响,父元素在计算其高度时,加入了浮动元素的高度,“顺便”达成了清除浮动的目标,所以父元素就包裹住了子元素)

如何创建BFC:

1.float不为none

2.overflow不为visible

3.position不为static或relative

4.display是lnline-block,inline-flex,flex,table-cell,table-caption

34.typyof和instanceof

typeof用来判断基本数据类型,返回的是字符串,但是对于null,object和array返回的都是object。

instanceof一个变量是否属于某个对象的实例,返回的是Boolean类型,判断某个构造函数的prototype属性是否存在对象的原型链上。

下面手写实现一下instanceof方法

function test_instanceof(L, R) {
    let LL = L.__proto__
    let RR = R.prototype
    while (true) {
        if (LL === null) return false
        if (RR === LL) return true
        LL=LL.__proto__
    }
}
function t() {   }
let a = new t()
console.log(test_instanceof(a,t)) //true
console.log(test_instanceof(a,Object)) //true
           

35.构造函数和普通函数的区别

构造函数可以生成实例对象

调用方式不同:构造函数用new关键字调用

首字母大小写:构造函数首字母一般大写

this指向不同:普通函数this指向window,构造函数的this指向创建的实例对象。

36.原型,原型对象

原型对象:构造函数prototype指向的就是原型对象

原型:函数有原型,函数的这个原型指向一个对象即原型对象

37.js继承

1.原型链继承:父类的实例充当子类的原型对象

缺点:父类的属性是所有子类共享的,不能多继承

function father() {  }
function son() {}
son.prototype=new father()
           

2.构造函数继承:借用父类的构造函数来增强子类实例,等于是把父类的实例属性复制一份给子类实例,可以多继承

缺点:无法实现函数的复用,实例并不是父类的实例,只是子类的实例,只继承父类,不继承原型

function Super(val){
  this.val = val;//可以传递参数
  this.arr = [1];
}
function Sub(val){
    Super.call(this,val);//核心代码
    //通过call()和apply()方法在新创建的对象上执行构造函数
}
           

3.组合式继承:使用原型链实现对原型属性和方法的继承,而通过构造函数来实现对实例属性的继承。

function Parent(name){
            this.name = name;
            this.colors = ['red', 'blue', 'green'];
        }
        Parent.prototype.getName = function(){
            console.log(this.name);
        }
        function Child(name,age){
            Parent.call(this,name);// 第二次调用 Parent()
            this.age = age;
        }
        Child.prototype = new Parent(); // 第一次调用 Parent()
           

38.call,apply,bind

第一个参数都是this要指向的对象,call第二个参数是参数列表的方式传入,apply第二个参数是数组的方式传入

call与apply是立即调用,bind是返回对应函数,需要时调用

function show(x){
			console.log(x);
		}
		let person={
			name:"aa",
		};
		show.call(person,"男");
		show.apply(person,["女"]);
		let ss=show.bind(person,"111");
		ss()
           

bind的实现

39.深拷贝的实现

40.promise

Promise,就是一个对象,用来传递异步操作的消息,可以进行异步操作

async await 解决回调地狱,语法糖

async function test1(){
    console.log("11")
    await test()
    console.log("22")
}
test1()
new Promise(function (resolve) {
    console.log("33")
       resolve();
}).then(function () {
    console.log("44")
})
function test() {
    console.log("test")
}
//11 test 33 22 44
           

macro-task(宏任务):包括整体代码script,setTimeout,setInterval

micro-task(微任务):Promise.then,process.nextTick

补充一个宏任务和微任务

前端可能问到的面试题(ts,js,css,es6)
前端可能问到的面试题(ts,js,css,es6)

41.强缓存和协商缓存

浏览器第一次向服务器发起请求时,服务器响应请求后,浏览器端会进行缓存。服务器会将最后一次修改时间last-modified发送给客户端进行记录,同时还会生成并发送Etag

强缓存

:浏览器请求资源时,会获取该资源缓存的header信息,根据cache-control判断是否从缓存中获取资源。

cache-control:max-age=31536000,public,immutable
           

max-age:缓存时间(s)

public:服务器和浏览器都可以缓存

immutable:资源永远改变(用户刷新浏览器也不发送请求)

协商缓存

:浏览器每次请求资源时,向服务器发送请求并且携带header中的Etag和last-modified,服务器判断是否改变,如果改变就返回新的资源和新的etag,last-modified以及200状态码。如果没有改变,返回304状态码,浏览器就读取本地资源。

注意服务器端header会改变

// response header
etag: '5c20abbd-e2e8'
last-modified: Mon, 24 Dec 2018 09:49:49 GMT

// request header 变为
if-none-matched: '5c20abbd-e2e8'
if-modified-since: Mon, 24 Dec 2018 09:49:49 GMT
           

已经有last-modified为什么要使用etag

1.有些资源的改变在1s内改变多次,last-modified对这种操作无法精确

2.某些请求是周期性的,没有修改内容,

3.某些服务器无法精确到最后修改时间

42.JSON.parse()和JSON.stringity()

JSON.parse():一个字符串中解析出json

JSON.stringity():从一个对象中解析出字符串

继续阅读