JavaScript面试题

JavaScript

typeof和instanceof的区别

typeof 运算符,在使用 typeof 运算符时采用引用数据类型存储值会出现一个问题,无论引用的是什么类型的对象,它都返回 "object" instanceof 解释:判断 b 是否是 A 的实例或者 A 的子类的实例

事件循环机制(eventloop)

同步任务会立刻执行,进入到主线程当中,异步任务会被放到任务队列(Event Queue)当中。Event Queue 单词的意思就是任务队列。 等待同步代码执行完毕后,返回来,再将异步中的任务放到主线程中执行,反复这样的循环,这就是事件循环。也就是先执行同步,返回来按照异步的顺序再次执行

promise原理、用法、API

js中的promise详解 - ming1025 - 博客园

promise的核心原理其实就是发布订阅模式,通过两个队列来缓存成功的回调(onResolve)和失败的回调(onReject),promise是异步编程的一种解决方案,解决多个异步方法串行的问题,比如回调地狱等问题

Promise是一个构造函数,自己身上有all、allsettled、any、race、reject、resolve这些静态方法,原型上有then、catch等方法,因此Promise new出来的对象肯定就有then、catch方法

同时发起多个请求可以使用promise.all

有三种可切换状态:pending(进行中)、resloved()、rejected()

promise状态只能从pending态转onfulfilled,onrejected到resolved或者rejected

基本用法:

可以通过Promise的构造函数创建Promise对象

Promise构造函数接收一个函数作为参数,该函数的两个参数是resolvereject,其中resolve函数的作用是当Promise对象转移到成功,调用resolve并将操作结果作为其参数传递出去;reject函数的作用是单Promise对象的状态变为失败时,将操作报出的错误作为其参数传递出去

reject方法

reject的作用就是把Promise的状态从pending置为rejected,这样在then中就能捕捉到reject的回调函数

then方法

可以使用链式调用,then方法可以接受两个参数,第一个对应resolve的回调,第二个对应reject的回调。所以我们能够分别拿到他们传过来的数据

通常使用axios在发请求的时候使用.then方法,因为axios已经封装好了promise

catch() 方法

和then的第二个参数一样,用来指定reject的回调--------即便是有错误的代码也不会报错,与try/catch语句有相同的功能

all

all方法提供了并行执行异步操作的能力,在all中所有异步操作结束后才执行回调,可以用来同时发多个请求,在写商品分类的时候就有用到promise.all

race

race则不同它等到第一个Promise改变状态就开始执行回调函数。将上面的all改为race,得到

宏任务微任务

宏任务:就是js内部队列里的任务,严格按照事件顺序压栈和执行,例如,settimeout、setintelval、Promise内部需要执行的任务就是宏任务; ​ 微任务:通常来说就是需要在当前 任务 执行结束后立即执行的任务,例如:nextTick、.then; 先执行宏任务,执行完宏任务会查看有没有微任务,没有继续执行下一次宏任务,有的话执行完全部微任务后继续执行下一次宏任务 ​ 宏任务中,Promise优先级高于setTimeout,微任务中:nextTick优先级高于.then

跨域

跨域出现的原因:浏览器的同源策略,同源策略主要用来防止CSRF攻击,同源策略会阻止一个域的JavaScript脚本和另外一个域的内容进行交互

出现跨域的场景:域名、端口号、协议有任何一个不一样的时候,就会出现跨域

解决:

1、一般没碰见过,通常都是后端解决

2、cors,在响应头中加入Access-Control-Allow-Origin:*(cors)

前端的话: 1、jsonp 原理:就是通过动态创建script标签,然后利用src属性进行跨域,href,src等请求下来的文件是不存在跨域问题的, 缺点:只能发送get一种请求

2、前端配置代理服务器,vue中:是在vue.config.js文件内,导出一个对象,对象里边有一个devServer属性,在这个里边配置proxy,react中

3、反向代理,nginx反向代理接口跨域

什么是反向代理?

客户端本来可以直接通过HTTP协议访问某网站应用服务器,网站管理员可以在中间加上一个Nginx,客户端请求Nginx,Nginx请求应用服务器,然后将结果返回给客户端,此时Nginx就是反向代理服务器

4、WebSocket协议跨域

但是在公司里边没遇见过跨域问题,后端都是解决好了的。

http、https

区别:

1、HTTP 明文传输,数据都是未加密的,安全性较差,HTTPS数据传输过程是加密的,安全性较好

2、HTTP 页面响应速度比 HTTPS 快,主要是因为 HTTP 使用 TCP 三次握手建立连接,客户端和服务器需要交换 3 个包,而 HTTPS除了 TCP 的三个包,还要加上 ssl 握手需要的 9 个包,所以一共是 12 个包

3、HTTPS 其实就是建构在 SSL/TLS 之上的 HTTP 协议,所以,要比较 HTTPS 比 HTTP 要更耗费服务器资源

在浏览器地址栏键入URL,按下回车之后会经历哪些流程

1.浏览器向DNS服务器请求解析该URL中的域名所对应的IP地址; ​ 2.解析出IP地址后,根据该IP地址和默认端口80,和服务器建立TCP连接; ​ 3.浏览器发出读取文件的HTTP请求,该请求报文作为TCP三次握手的第三个报文的数据发送给服务器; ​ 4.服务器对浏览器请求作出响应,并把对应的html文本发送给浏览器; ​ 5.释放TCP ​ 6.浏览器将该html文本并显示内容

https原理:

(1)客户使用https的URL访问Web服务器,要求与Web服务器建立SSL连接。

  (2)Web服务器收到客户端请求后,会将网站的证书信息(证书中包含公钥)传送一份给客户端。

  (3)客户端的浏览器与Web服务器开始协商SSL连接的安全等级,也就是信息加密的等级。

  (4)客户端的浏览器根据双方同意的安全等级,建立会话密钥,然后利用网站的公钥将会话密钥加密,并传送给网站。

  (5)Web服务器利用自己的私钥解密出会话密钥。

  (6)Web服务器利用会话密钥加密与客户端之间的通信。

三次握手(TCP)

客户端向服务端发送请求,服务端收到后给客户端发送返回值,客户端收到后再次给服务端发送表示客户端有接收能力

四次挥手

客户端发送一个我要断开的消息给服务端,服务端接收到到之后发送消息给客户端我已经进入关闭等待状态;服务端再次发送消息告诉客户端,这个是我最后一次发消息给你,当我再次接收到消息的时候就会关闭;客服端接受到服务端的消息之后,告诉服务器,我已经关闭,这个是给你最后一个消息

Http缓存分类(强缓存和协商缓存)

缓存的优点: 减少了不必要的数据传输,节省带宽 减少服务器的负担,提升网站性能 加快了客户端加载网页的速度 用户体验友好 缺点: 资源如果有更改但是客户端不及时更新会造成用户获取信息滞后,如果老版本有bug的话,情况会更加糟糕。 强缓存: 当浏览器去请求某个文件的时候,服务端就在respone header里面对该文件做了缓存配置。缓存的时间、缓存类型都由服务端控制,具体表现为: respone header 的cache-control,常见的设置是max-age public private no-cache no-store等

协商缓存: 强缓存就是给资源设置个过期时间,客户端每次请求资源时都会看是否过期;只有在过期才会去询问服务器。所以,强缓存就是为了给客户端自给自足用的。而当某天,客户端请求该资源时发现其过期了,这时就会去请求服务器了,而这时候去请求服务器的这过程就可以设置协商缓存。 response header里面的设置 etag:每个文件有一个,改动文件了就变了,就是个文件hash,每个文件唯一,就像用webpack打包的时候,每个资源都会有这个东西 last-modified:文件的修改时间,精确到秒

常见状态码

200: '服务器成功返回请求的数据。', ​ 201: '新建或修改数据成功。', ​ 202: '一个请求已经进入后台排队(异步任务)。', ​ 204: '删除数据成功。', ​ 400: '发出的请求有错误,服务器没有进行新建或修改数据的操作。', ​ 401: '用户没有权限(令牌、用户名、密码错误)。', ​ 403: '用户得到授权,但是访问是被禁止的。', ​ 404: '发出的请求针对的是不存在的记录,服务器没有进行操作。', ​ 405: '请求方法不被允许。', ​ 406: '请求的格式不可得。', ​ 410: '请求的资源被永久删除,且不会再得到的。', ​ 422: '当创建一个对象时,发生一个验证错误。', ​ 500: '服务器发生错误,请检查服务器。', ​ 502: '网关错误。', ​ 503: '服务不可用,服务器暂时过载或维护。', ​ 504: '网关超时。',

axios原理

Axios 是一个基于 promise 的 HTTP 库

特点:支持请求、响应拦截器,安全性更高,客户端支持防御 XSRF

xss、sxrf攻击

XSS攻击: 攻击者通过在目标网站上注入恶意脚本,使之在用户的浏览器上运行。利用这些恶意脚本,攻击者可获取用户的敏感信息如 Cookie、SessionID 等,进而危害数据安全。 防范XSS攻击: httpOnly: 在 cookie 中设置 HttpOnly 属性后,js脚本将无法读取到 cookie 信息。 输入过滤:1:检测按照规定的格式输入,2:转义HTML,把引号,尖括号,斜杠进行转义 CRFS攻击: 一种挟制用户在当前已登录的 Web 应用程序上执行非本意的操作的攻击方法。 防御CSFS攻击: 验证码:强制用户必须与应用进行交互,才能完成最终请求。 设置token

cookie 、localstorage和session的区别

1、cookie: cookie的内容主要包括:name(名字)、value(值)、expire(有效时间)、path(路径)和Domain(域)后俩可选。路径与域一起构成cookie的作用范围。若不设置时间,关闭浏览器窗口,cookie就会消失。 cookie数据存放在客户的浏览器上。单个cookie保存的数据不能超过4K。session大小没有限制,此外cookie还分为客户端cookie和服务端cookie

session中保存的是对象,cookie中保存的是字符串,以文本的方式 ​ session不能区分路径,同一个用户在访问一个网站期间,所有的session在任何一个地方都可以访问到,而cookie中如果设置了路径参数,那么同一个网站中不同路径下的cookie互相是访问不到的 ​ session数据放在服务器上

2、localStorage:将数据保存在客户端本地的硬件设备(通常指硬盘,也可以是其他硬件设备)中,即使浏览器被关闭了,该数据仍然存在,下次打开浏览器访问网站时仍然可以继续使用。理论上是永久有效的,不清空就不会消失,即使保存的数据超出了浏览器的规定大小,也不会把旧数据清空,只是报错

3、sessionStorage:将数据保存在session对象中。所谓session,是指用户在浏览某个网站时,从进入网站到浏览器关闭所经过的这段时间,也就是用户浏览这个网站所花费的时间。session对象可以用来保存在这段时间内所要求保存的任何数据。

这两者的区别在于,sessionStorage为临时保存,而localStorage为永久保存。

应用场景:localStoragese:常用于长期登录(+判断用户是否已登录),适合长期保存在本地的数据。sessionStorage:敏感账号一次性登录;

es6

es6和es5的区别:

新增了太多东西

1、let 局部变量和 const 常量声明关键字

let 变量没有声明提升,不能重复定义,产生块级作用域

2、解构赋值 4、展开运算符 5、模板字符串

3、箭头函数(箭头函数里面没有自己的this,箭头函数里的this指向上下文)

4、Array.from():把伪数组转成数组,伪数组必须有length属性,如果没有将返回一个空数组;转换后的数组的长度,是根据伪数组的length决定的 5、数组 find( )和 findIndex( ) 方法

find()用于查找数组中的值,findIndex():用于查找数组的下标,用法与find一样 ​ find找到数组中的第一个满足条件的成员并返回该成员的索引,如果找不到返回undefined ​ findIndex找到数组中第一个满足条件的成员并返回该成员的索引,如果找不到返回-1 6、includes():判断数组是否包含某个值,返回true/false ​ 参数1,必须,表示查找的内容 ​ 参数2,可选,表示开始查找的位置,0表示开头的位置 7、startsWidth(str,[postion])返回布尔值,表示参数字符串是否在字符串的头部或指定位置 8、endsWith(str,[postion])返回布尔值,表示参数字符串是否在原字符串的尾部或指定位置 9、set对象,set对象中的成员不会有重复的

10、filter

var、let、const的区别

1.var定义的变量,没有块的概念,可以跨块访问, 不能跨函数访问。有变量提升 2.let定义的变量,只能在块作用域里访问,不能跨块访问,也不能跨函数访问。没有变量提升 3.const用来定义常量,使用时必须初始化(即必须赋值),只能在块作用域里访问,而且不能修改。没有变量提升

es7

求幂运算符(**)

es5新增数组方法

es5数组新增:

indexOf:indexOf(‘元素’) 查找数组中是否存在这个元素,如果存在返回下标,不存在返回-1

forEach:forEach 遍历数组

map :和forEach相似,可以使用return,返回一个新的数组

filter:按照条件筛选数组,返回一个新数组

reduce:可以用来数组对象求和

every:判断 数组所有的元素是否都满足条件

some:判断是否数组有一些元素满足条件

Array.isArray( ):判断是不是一个真数组真数组返回true,假返回 false

Array.form()转换为真数组

常用数组方法

push:头部添加元素,返回值是新数组的长度

splice:截取某些内容,reverse:反转数组,sort:排序,concat 多个数组进行拼接

join:链接数组里面的每一项内容,可以自己定义每一项之间的链接内容,indexOf:查找元素第一次出现的下标,找到返回下标,找不到返回-1

上边es5新增的加上es6新增 find、findIndex

数组去重

es6 Set去重(最常用) 直接new set(arr)把数组传进去就可以了,Set方法出来不是一个数组,需要用Array.form转换为数组

indexOf 定一个空数组,循环遍历,使用indexOf判断数组中有没有这个元素,没有会返回-1,判断==-1的时候把元素push进新数组

sort、includes、filter都可以,但是我不常用

浅拷贝深拷贝

浅拷贝:浅拷贝只复制对象的第一层属性,而不复制对象本身,新旧对象还是共享同一块内存;修改新对象影响原对象

深拷贝:会另外创造一个一模一样的对象,新对象和原对象不共享内存,修改新对象不会改到原对象

浅拷贝:

Object.assign(目标对象, 源对象),源对象的所有可枚举属性都复制到目标对象上 ​ ...展开运算符 ​ concat方法 ​ var arr1 = [1, 2, 3, 4] ​ var arr2 = arr1.concat()//复制当前数组并返回实现深拷贝的副本,arr1独立而不受影响 ​ console.log(arr2);[1, 2, 3, 4]

深拷贝:

1、json方法:

定一个对象,定义变量将对象转换为json字符串形式,在定义一个变量将转换而来的字符串转换为原生js对象就可以了

2、函数库lodash的_.cloneDeep方法

3、递归实现深拷贝

闭包

什么是闭包:外部函数 内部 定义一个内部函数,内部函数使用的外部函数的局部变量,外部函数返回了内部函数

优点: 希望一个变量长期存储在内存中。 避免全局变量的污染。 私有成员的存在。 缺点: 常驻内存,增加内存使用量。 使用不当会很容易造成内存泄露。

使用场景:防抖:在事件被触发n秒后再执行回调,如果在这n秒内又被触发,则重新计时。

setTimeout :原生的setTimeout传递的第一个函数不能带参数,通过闭包可以实现传参效果。

作用域链

使用一个变量的时候自身找,没有的就去父级,以次类推

全局变量:声明的变量是使用var声明的,那么这个变量就是全局变量,全局变量可以在页面的任何位置使用

除了函数以外,其他的任何位置定义的变量都是全局变量

局部变量:在函数内部定义的变量,是局部变量,外面不能使用

全局变量,如果页面不关闭,那么就不会释放,就会占空间,消耗内存

全局作用域:全局变量的使用范围

局部作用域:局部变量的使用范围

块级作用域:一对大括号就可以看成是一块,在这块区域中定义的变量,只能在这个区域中使用,

但是在js中在这个块级作用域中定义的变量,外面也能使用;

说明:js没有块级作用域,只有函数除外

隐式全局变量:声明的变量没有var,就叫隐式全局变量

防抖和节流

相同:在不影响客户体验的前提下,将频繁的回调函数,进行次数缩减,避免大量计算导致的页面卡顿, 不同:

防抖:将多次执行变为最后一次执行,就是指触发事件后在n秒内函数只能执行一次,如果在n秒内又触发了事件,则会重新计算函数执行时间(input框,为了不让每次输入一个字符就打印,只打印最后输完的一次) ​ 节流:是将多次执行变为在规定时间内只执行一次,就是指连续触发事件但在n秒内只执行一次函数(下拉加载更多)。

应用场景:防抖就是百度input搜索框,每次键盘按下输入内容都会发起请求,加入防抖之后,会在内容输入完成之后才发起请求,还有身份验证的时候是同样的道理。

节流:下拉加载更多,在一定时间内发起一次请求,避免无线下拉一直发起请求

垃圾回收机制

什么是垃圾:一般来说没有被引用的对象就是垃圾,就是要被清除, 有个例外如果几个对象引用形成一个环,互相引用,但根访问不到它们,这几个对象也是垃圾,也要被清除。

标记清除算法

缺陷:

那些无法从根对象查询到的对象都将会被清除

垃圾收集后有可能会造成大量垃圾碎片

引入计数算法

跟踪记录每个值被应用的次数。

当声明一个变量 并将一个引用类型的值赋给该变量时 则这个值得引用次数就是1 如果同一个值又赋给另一个变量时 引用次数+1

相反 如果包含这个值的变量又取得另外一个值 那么该值得引用次数-1

当这个值得引用次数变成0的时候 则说明没有办法再访问这个值 当下次垃圾收集器下次再运行 就会清理掉引用次数为0的值

缺陷:

无法处理循环引用。 如果两个对象创建并互相引用 形成一个循环。考虑到他们互相都有一次引用,所以不会被回收

原型和原型链

原型:每个构造函数都有一个原型属性 prototype 保存了所有用构造函数实例化出来对象的方法,用构造函数创建一个对象,这个对象上会有一个属性proto 指向构造函数的原型属性,

原型链:当我们使用一个对象的属性或者方法的时候,首先在自身内存查找,找到就用,找不到就去原型上找。原型的本质对象,对象又有自己的原型 ,原型如果没有这个方法,就去原型的原型中查找,这个查找的链条就叫做原型链,最后找到Object.prototype 如果Object.prototype 没有这个属性,直接返回undefind,因为Object.prototype 的原型是null

继承(口述代码)

1、原型链继承 让新实例的原型等于父类的实例。 2、借用构造函数继承 用.call()和.apply()将父类构造函数引入子类函数 3、组合继承(常用)0 结合原型链和构造函数两种模式的优点,传参和复用 缺点:调用了两次父类构造函数(耗内存),子类的构造函数会代替原型上的那个父类构造函数。 4、原型式继承 用一个函数包装一个对象,然后返回这个函数的调用,这个函数就变成了个可以随意增添属性的实例或对象。object.create()就是这个原理。 5、寄生式继承 就是给原型式继承外面套了个壳子 6、寄生组合式继承 (1)在函数内返回对象然后调用,函数的原型等于另一个实例。 (2)在函数中用apply或者call引入另一个构造函数,可传参 重点是修复了组合继承的缺点 js继承的6种方式 - ranyonsue - 博客园

常见设计模式

工厂模式、抽象工厂模式、单例模式、原型模式、适配器模式

发布订阅者模式

其实24中设计模式中没有发布订阅者模式,只是观察者模式的一个别称, 现在的发布订阅者模式,称为发布者发送消息不会直接发给订阅者,而是通过一个发布者和订阅者之间的第三个组件,称为消息代理或中间件,它维持着发布者和订阅者之间的联系,过滤所有发布者传入的消息并相应的分发给他们的订阅者。 举一个例子,你在微博关注了A,同时很多人也关注了A,当A发送动态的时候,微博就会为你们推送这条动态,这时候A就是发布者,你是订阅者,微博是调度中心,你和A是没有直接往来的,都是通过微博来协调的。

发布订阅者模式和观察者模式的区别

观察者模式定义了对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都将得到通知,并自动更新 ​ 他俩的区别可能就是发布订阅者模式多了个事件调度中心

箭头函数的好处(箭头函数和普通函数的区别)

箭头函数本身没有prototype所以箭头函数本身没有this 箭头函数的this永远指向其上下文,call()bind()apply()改变不了其this的指向 普通函数的this指向调用它的那个对象 箭头函数相当于一个匿名函数 不能作为构造函数 不能new 箭头函数不能换行,换行需要return,

this指向

普通函数调用,this指向window,

定时器函数,this指向window,

构造函数调用,this指向实例对象,

对象方法调用,this指向该方法所属对象,

事件绑定时,this指向绑定事件的对象,

箭头函数,this指向上下文

更改this指向的三个方法:call( )、apply( )、bind( )

三者区别:bind 会有一个返回值,返回值是个函数,因此要加上()才能调用;call,apply是没有返回值,当改变函数this指向的时候,不需要加()就会执行,call 传递参数的时候是一个一个传递的, apply是传递一个数组

正则

\d 0-9任一数字,\D 0-9以外所有的字符,\w 任意字母、数字和下划线,\W 除字母数字下划线以外的字符 \s 匹配空格(换行符、制表位、空格符等),\S 匹配非空格的字符, . 匹配除 \ n(换行)之外的任何单个字符

conmonjs规范(AMD和commonjs规范)

1.相同点:都是为了模块化。

2.不同点:AMD规范则是非同步加载模块,允许指定回调函数。CommonJS规范加载模块是同步的,也就是说,只有加载完成,才能执行后面的操作。

commentjs的特点: 所有代码都运行在模块作用域,不会污染全局作用域。

模块可以多次加载,但是只会在第一次加载时运行一次,然后运行结果就被缓存了,以后再加载,就直接读取缓存结果。要想让模块再次运行,必须清除缓存。

module.exports属性表示当前模块对外输出的接口,其他文件加载该模块,实际上就是读取module.exports变量。 require命令用于加载模块文件,相当于读入并执行一个js文件,然后返回该模块的exports对象,没有发现指定模块,则就会报错。

js的作用域有哪些

全局作用域(es5)

最外层函数和在最外层函数外面定义的变量拥有全局作用域

所有末定义直接赋值的变量自动声明为拥有全局作用域

所有window对象的属性拥有全局作用域

局部作用域,也叫函数作用域(es5)

声明在函数内部的变量,和全局作用域相反,局部作用域一般只在固定的代码片段内可访问到

块级作用域(es6)

let和const 声明变量都是块级作用域,没有变量提升声明在函数内部的变量,和全局作用域相反,局部作用域一般只在固定的代码片段内可访问到,最常见的例如函数内部,所有在一些地方也会看到有人把这种作用域称为函数作用域(所有没有var直接赋值的变量都属于全局变量)

获取url地址参数

通过location.search获取到地址栏中?后边的参数

然后用URLSearchParams方法

let obj = new URLSearchParams(str) 定义一个对象接收,使用get方法获取到=前那个字段后边跟着得参数

提高网站性能,网站优化性能

1、减少http请求数量,浏览器到服务器之间是需要经过三次握手的,每次握手需要花大量时间,不同浏览器对资源文件的请求数量是有限的,可以通过减少http请求来减少 2、控制资源文件的加载优先级,比如说某些css文件或者js文件是触发到某个事件的时候才会用到,不一定是上来的时候都要加载,这样子的话,就排一个优先级顺序,这样子用到的时候再加载,用不到的时候就不用加载,一般就是把css放在头部,js放在底部 3、利用浏览器缓存,直接将浏览器网络资源存储在本地,然后下次去请求的时候,如果本地资源已经有了,就不需要到浏览器重新请求资源了,如果没有再去读取网络资源,

空数组和空对象的判断

ar arr = []; var str = JSON.stringify(arr); if(arr.length !== 0) { console.log('真') } else { console.log('假') } if(str !== "[]") { console.log('真') } else { console.log('假')

}

空对象的判断

var obj = {}; var objStr = JSON.stringify(obj); if(objStr !== "{}") { console.log('真'); } else { console.log('假') } if(Object.keys(obj).length == 0) { console.log('真'); } else { console.log('假');

for in 循环判断 var obj = {}; var b = function() { for(var key in obj) { return false; } return true; } alert(b());//true

html+css

css3

伪类选择器::first-child,:last-child,:last-child, :link,:visitied,:hover,:active,:checked 伪元素:::after,::before,::first-line 选择器:nth-child(n) nth-of-type(n)(只会把指定元素的盒子排列序号,而nth-child(n)会把所有盒子都排列序号) 伪元素选择器:::before,::after(创建的元素属于行内元素,伪元素选择器和标签选择器一样,权重为1) 盒模型:box-sizing:content-box/border-box filter函数,例如:filter:blur(5px);blur模糊处理,数值越大越模糊 calc函数,让在声明css属性时执行一些计算,例如:width:calc(100% - 80px) 过渡:transtion:要过渡的属性,花费时间,运动曲线,何时开始 flex布局 rem(相对于html元素的字体大小) em(相对于父元素字体大小) vw vh

三栏布局

.layout.absolute .left { position: absolute; left: 0; width: 300px; } .layout.absolute .center { margin: 0 300px 0 300px; } .layout.absolute .right { position: absolute; right: 0; width: 300px;

        }    

flex弹性盒

flex-direction 设置主轴方向:

row 默认主轴水平,起点在左 | row-reverse 水平 在右| column 垂直 起点上沿| column-reverse 起点下沿 justify-content 设置在主轴上的对齐方式:

flex-start 默认左对齐 | flex-end 右对齐| center 居中 | space-between 两端对齐,子元素之间的间隔都相等 | space-around 两端对齐,子元素之间的间隔都相等 algin-items 设置在交叉轴上对齐方式:

flex-start 交叉轴的起点对齐| flex-end 交叉轴的终点对齐| center 中点对齐| baseline 子元素的第一行| stretch 若项目为设置高度或设置为auto,将占满整个父元素 flex-wrap 设置是否换行:

nowrap 默认 不换行| wrap 换行 首行在上| wrap-reverse 换行 首行在下 align-content:

flex-start | flex-end | center | space-between | space-around 设置多根轴线的对齐方式,如果项目只有一根轴线,该属性不起作用。 align-self:auto | flex-start | flex-end | center | baseline | stretch 设置单个项目与其他项目不一样的对齐方式 order:数值越小,排列越考前,默认为0,定义项目的排列顺序 flex-gorw:默认为0,即如果存在剩余空间,也不放大 flex-shrink:默认为1,即如果空间不足,该项目缩小

怪异盒模型

语法:box-sizing: border-box怪异/content-box标准

标准盒模型的总大小=width/height+padding+border+margin

怪异盒模型下盒子的大小=width(content + border + padding) + margin

position定位

relative:相对定位,根据right;top;left;bottom等属性,相对自己原来的位置偏移,原位置还会占位置。 添加给父元素做辅助作用

absolute:绝对定位,不占位置 父元素有定位属性根据父元素位置来定位自己的位置,父元素没有根据html定位

fixed:固定定位,不占位置,根据浏览器的窗口(html)来定义自己的位置

stiky,粘性定位,滚动框、占位置

z-index,层叠属性

4种水平垂直居中的办法

一,弹性盒 display:flex; justify-content:center;align-items:center; 二,定位 position:absolute; top:0;right:0;button:0;left:0;margin:auto; 三,margin+定位 position:absolute; left:50%;top:50%;margin-top:-50px;(元素高的一半);margin-left:-100px(元素宽的一半) 四,transform:translate+定位 position:absolute; left:50%,top:50%,transform:translate(-50%,-50%)

动画和过渡

transform动画、transition过渡

单行、多行文本溢出显示省略号

1、容器定义一个宽度

2、white-space:nowrap 强制文本在一行显示

3、overflow:hidden 溢出内容为隐藏

4、text-overflow:ellipse 溢出文本显示省略号

多行文本:-webkit-line-clamp用来限制在一个块元素显示的文本的行数

要结合这俩属性display: -webkit-box 将对象作为弹性伸缩盒子模型显示,-webkit-box-orient 设置或检索伸缩盒对象的子元素的排列方式

浏览器内核

IE:trident,谷歌:webkit(前) blink(现),Safari:webkit,火狐:Gecko

购物车结算时的误差怎么处理

let val = Math.round(价格*100) let res = val / 100

小数可以先放大一百倍,然后再缩小一百倍。

null和underfined的区别

null 表示一个值被定义了,定义为“空值”;null的类型是Object undefined 表示根本不存在定义。underfined的类型为underfined

判断数据类型的四种方法

1、typeof 最基础的,其右侧跟一个一元表达式,并返回这个表达式的数据类型 2、instanceof 用来判断A是否为B的实例,表达式为:A instanceof B,如果A是B的实例,则返回true,否则返回false。instanceof检测的是原型,内部机制是通过判断对象的原型链中是否有类型的原型。 3、constructor 当一个函数F被定义时,JS引擎会为F添加prototype原型,然后在prototype上添加一个constructor属性,并让其指向F的引用,F利用原型对象的constructor属性引用了自身,当F作为构造函数创建对象时,原型上的constructor属性被遗传到了新创建的对象上,从原型链角度讲,构造函数F就是新对象的类型。 这样做的意义是,让对象诞生以后,就具有可追溯的数据类型。 4、Object.prototype.toString toString()是Object的原型方法,调用该方法,默认返回当前对象的类型,格式是[object,xxx],对于Object对象,直接调用toString()就能返回[object Object],而对于其他对象,则需要通过call、apply来调用才能返回正确的类型信息。

自适应和响应式布局(rem)

px:像素单位,em:参数父元素字体大小,rem:参照根元素字体大小,vw:参照视窗宽度的百分比,vh:视窗高度百分比

自适应布局原理:分别为不同的屏幕分辨率定义布局,即创建多个静态布局,每个静态布局对应一个屏幕分辨率范围,改变屏幕分辨率可以切换不同的静态局部(页面元素位置发生改变),但在每个静态布局中,页面元素不随窗口大小的调整发生变化。

响应式布局原理是:网页的布局针对屏幕大小的尺寸而进行响应;

圣杯布局(自适应三栏)、双飞翼(自适应三栏)

移动端适配

使用rem当做距离单位,在根元素html里边设置一个font-size大小

渐进增强、优雅降级

渐进增强(Progressive Enhancement):一开始就针对低版本浏览器进行构建页面,完成基本的功能,然后再针对高级浏览器进行效果、交互、追加功能达到更好的体验。

优雅降级(Graceful Degradation):一开始就构建站点的完整功能,然后针对浏览器测试和修复。比如一开始使用 CSS3 的特性构建了一个应用,然后逐步针对各大浏览器进行 hack 使其可以在低版本浏览器上正常浏览

区别:优雅降级是从复杂的现状开始,并试图减少用户体验的供给,而渐进增强则是从一个非常基础的,能够起作用的版本开始,并不断扩充,以适应未来环境的需要。降级(功能衰减)意味着往回看;而渐进增强则意味着朝前看,同时保证其根基处于安全地带。

高度塌陷

1、给父元素添加声明overflow:hidden;

2、在浮动元素下方添加空div,并给该元素添加声明:clear:both;height:0;overflow:hidden;

BFC生成规则

1、内部的Box会在垂直方向上一个接一个的放置

2、垂直方向上的距离由margin决定,属于同一个BFC的两个相邻Box的margin会发生重叠。

3、每个元素的margin box的左边, 与包含块border box的左边相接触

4、BFC的区域不会与float的元素区域重叠

5、计算BFC的高度时,浮动子元素也参与计算

6、BFC就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面元素,反之亦然

css手写三角形和圆

写一个div,宽高都

#triangle-up { width: 0; height: 0; border-left: 50px solid transparent; border-right: 50px solid transparent; border-bottom: 100px solid red; }

写个div border-reduces 宽高的一半

你可能感兴趣的:(javascript,面试,vue.js)