前端面试题

1、基于vue的前端性能优化

基于vue的web前端性能优化 - 深海鱼veritas - 博客园2

2、BFC布局

什么是BFC布局——浅析BFC布局的概念以及作用3

3、js执行机制

js执行机制 - 简书

4、计算属性与监听器的区别

区别:

1、计算属性的应用场景是计算的内容需要依赖多个属性的情况
侦听器的应用场景是计算的内容依赖一个属性的情况
2、计算属性缓存结果时每次都会重新创建变量
而侦听器是直接计算,不会创建变量保存结果
也就意味着,数据如果会反复的发生变化,计算很多次的情况下,计算属性的开销将会更大,也就意味着这种情况不适合使用计算属性,适合使用侦听器
那么,如果一个数据反复会被使用,但是它计算依赖的内容很少发生变化的情况下,计算属性会缓存结果,就更加适合这种情况。
3、computed的结果是通过return返回的,而watch不需要return。
4、watch中的参数可以得到侦听属性改变的最新结果,而computed函数没有这种参数。

补充:
watch只会监听数据的值是否发生改变,而不会监听地址的变化,如果需要监听引用类型的数据变化,需要深度监听:obj:{handler(newVal){},deep:true}------用handler+deep的方式进行深度监听。
在特殊的情况下(更改数组中的数据时,数组已经更改,但是视图没有更新),watch无法监听数组的变化,更改数组必须要用splice()或者$set。


结论:

我们在计算开销比较大(计算次数多或者异步处理)的时候,会使用侦听器watch来得到计算结果。
而其他情况建议使用计算属性computed,因为缓存节省多次计算的性能。

原文链接:计算属性(computed)和监听器(watch)的区别_itcast_cs的博客-CSDN博客_计算属性和监听属性的区别

5、h5和c3特性

H5 和 CSS3 新特性 - 筱月 - 博客园

HTML5+CSS3新增内容总结!!!!!绝对干货 - 王郝 - 博客园

6、清除浮动的四种常见方法、以及优缺点

清除浮动的最常用的四种方法,以及优缺点_h_qingyi的博客-CSDN博客_清除浮动

7、vue之mixin(混入)理解与适用

vue之mixin理解与使用 - 简书

8、三次握手和四次挥手

先来看看如何建立连接的

 首先Client端发送连接请求报文,Server段接受连接后回复ACK报文,并为这次连接分配资源。Client端接收到ACK报文后也向Server段发生ACK报文,并分配资源,这样TCP连接就建立了。

那如何断开连接呢?

【注意】中断连接端可以是Client端,也可以是Server端。

假设Client端发起中断连接请求,也就是发送FIN报文。Server端接到FIN报文后,意思是说"我Client端没有数据要发给你了",但是如果你还有数据没有发送完成,则不必急着关闭Socket,可以继续发送数据。所以你先发送ACK,"告诉Client端,你的请求我收到了,但是我还没准备好,请继续你等我的消息"。这个时候Client端就进入FIN_WAIT状态,继续等待Server端的FIN报文。当Server端确定数据已发送完成,则向Client端发送FIN报文,"告诉Client端,好了,我这边数据发完了,准备好关闭连接了"。Client端收到FIN报文后,"就知道可以关闭连接了,但是他还是不相信网络,怕Server端不知道要关闭,所以发送ACK后进入TIME_WAIT状态,如果Server端没有收到ACK则可以重传。“,Server端收到ACK后,"就知道可以断开连接了"。Client端等待了2MSL后依然没有收到回复,则证明Server端已正常关闭,那好,我Client端也可以关闭连接了。Ok,TCP连接就这样关闭了!

原文链接:详解三次握手和四次挥手(一看就懂哦)_su_bao的博客-CSDN博客_三次握手和四次挥手

9、v-if和v-for一起使用的几种处理方式

我们希望的情况是先判断是否满足条件(v-if一次),满足的话就开始循环,但是v-for优先级比较高,一起使用的话,会先循环,然后在每次循环里面都来一次v-if。这样会消耗性能。

(1)如果避免出现这种情况,则在外层嵌套template(页面渲染不生成dom节点),在这一层进行v-if判断,然后在内部进行v-for循环

<template v-if="isShow">
    <p v-for="item in items">
</template>

(2)如果条件出现在循环内部,可通过计算属性computed提前过滤掉那些不需要显示的项

computed: {
    items: function() {
      return this.list.filter(function (item) {
        return item.isShow
      })
    }
}

Vue中v-if和v-for的一起使用时的几种处理方式_五花漏的博客-CSDN博客

10、闭包

原文链接:「每日一题」JS 中的闭包是什么? - 知乎

彻底理解js中的闭包_dovlie的博客-CSDN博客_闭包

11、用jsonstringify缺点是什么,局限性

关于json:为何不推荐使用JSONstringify做深拷贝 - 乐趣区

12、 模板字符串

反引号``

ES6模板字符串 - WhiteSpace - 博客园

13、csrf攻击防御

简介:

CSRF的全名为Cross-site request forgery,它的中文名为 跨站请求伪造(伪造跨站请求【这样读顺口一点】)

CSRF是一种夹持用户在已经登陆的web应用程序上执行非本意的操作的攻击方式。相比于XSS,CSRF是利用了系统对页面浏览器的信任,XSS则利用了系统对用户的信任。

 原理:

由上图分析我们可以知道构成CSRF攻击是有条件的:

  1、客户端必须一个网站并生成cookie凭证存储在浏览器中

  2、该cookie没有清除,客户端又tab一个页面进行访问别的网站

CSRF防御方法:

1、重要数据交互采用POST进行接收,当然是用POST也不是万能的,伪造一个form表单即可破解

2、使用验证码,只要是涉及到数据交互就先进行验证码验证,这个方法可以完全解决CSRF。

3、验证HTTP Referer字段,该字段记录了此次HTTP请求的来源地址,最常见的应用是图片防盗链。

4、为每个表单添加令牌token并验证

        要求:

          要确保同一页面中每个表单都含有自己唯一的令牌

          验证后需要删除相应的随机数

原文链接:CSRF攻击与防御 - 那一叶随风 - 博客园

14、http请求头中有什么

一、HTTP请求头是什么?

  HTTP请求头,HTTP客户程序(例如浏览器),向服务器发送请求的时候必须指明请求类型(一般是GET或者POST)。如有必要,客户程序还可以选择发送其他的请求头。

二、HTTP头中都有什么?

  1、请求类型:我们常见的请求类型有Get和Post两种请求,而这个信息在HTTP请求报文中的地一行即请求中就可以得到;

  2、请求地址:请求地址告诉服务端当前请求来自哪里,例如"/"表示的是服务器根目录,对一个静态网站而言,如果存在index.html

        则指向该网页;对一个动态网站而已,如果存在index.php则它指向该网页。

  3、请求参数:客户端和服务器的通信最终是要落实到具体数据的传递上来的,所以通过请求报文我们能够获得客户端传递的参数

        并对其进行处理,通常Get类型参数在请求行、而Post类型参数在消息体中。

  4、请求约束:我们把1、2、3是通信核心要素,那么接下来这些我们可以称其为细节要素。

  5、请求报文:

        第一部分:请求类型、请求参数、请求地址;

        第二部分:请求头部,这里定义了如Accept,AcceptLanguage等字段,这是我们这里所说的请求约束。

        第三部分,消息体,它是一个可选的内容,和第二部分间有一个空行,当采用Post类型请求时这里将记录客户端传递的参数。

原文链接:HTTP请求头中的那些东西 - 小郭程序员 - 博客园

15、http存储,请说出它们的区别

Cookie、session和localStorage、以及sessionStorage之间的区别 - web小白需努力 - 博客园

16、请求头cookie的缺点

谈谈Cookie的弊端

  • Cookie`数量和长度的限制。每个domain最多只能有20条cookie,每个cookie长度不能超过4KB,否则会被截掉。在当今新的浏览器和客户端设备版本中,支持 8192 字节的 Cookie 大小已愈发常见。
  • 用户配置为禁用。有些用户禁用了浏览器或客户端设备接收 Cookie 的能力,因此限制了这一功能
  • 由于在HTTP请求中的cookie是明文传递的,潜在的安全风险,Cookie 可能会被篡改
  • 有些状态不可能保存在客户端
  • cookie会被附加在每个HTTP请求中,所以无形中增加了流量
  • cookie一般不可跨域使用
  • 没有封装好的setCookie和getCookie方法,需要开发者自省封装
  • 参考网址whttps://blog.csdn.net/weixin_34247155/article/details/91386108

关于cookie的缺陷

17、http状态码

参考网址https://www.cnblogs.com/xflonga/p/9368993.html

18、axios中断(当我不想发送这个请求了,咋办)

// 获取CancelToken
const CancelToken = axios.CancelToken;
const source = CancelToken.source();

// http request 拦截器);
axios.interceptors.request.use(
  (config) => {
    // 全局添加cancelToken
    newConfig.cancelToken = source.token;
    return newConfig;
  },
  (err) => {
    const error = err;
    return Promise.reject(error);
  },
);

// http response 拦截器
axios.interceptors.response.use((response) => {
  const code = response.data.code;
  if (code == '002') {
    // 某个请求的响应满足特定条件的情况下,取消其他正在进行的请求
    source.cancel();
  }
  return Promise.resolve(response.data);
}, (error) => {
  if (axios.isCancel(error)) { // 取消请求的情况下,终端Promise调用链
    return new Promise(() => {});
  } else {
    return Promise.reject(error);
  }
});

原文链接:axios全局设置取消请求及中断Promise调用链 - 简书

19、axios请求拦截器

1、请求拦截器

请求拦截器的作用是在请求发送前进行一些操作,例如在每个请求体里加上token,统一做了处理如果以后要改也非常容易。

axios.interceptors.request.use(function (config) {
    // 在发送请求之前做些什么,例如加入token
    .......
    return config;
  }, function (error) {
    // 对请求错误做些什么
    return Promise.reject(error);
  });

2、响应拦截器

响应拦截器的作用是在接收到响应后进行一些操作,例如在服务器返回登录状态失效,需要重新登录的时候,跳转到登录页。

axios.interceptors.response.use(function (response) {
    // 在接收响应做些什么,例如跳转到登录页
    ......
    return response;
  }, function (error) {
    // 对响应错误做点什么
    return Promise.reject(error);
  });

3、移除拦截器

var myInterceptor = axios.interceptors.request.use(function () {/*...*/});
axios.interceptors.request.eject(myInterceptor);

原文链接:axios请求拦截器和响应拦截器 - 简书

20、插槽有哪些,简单说一说

普通插槽,具名插槽,作用域插槽

插槽允许我们在调用子组件的时候为子组件传递模板。

<slot> 元素作为承载分发内容的出口。 一个不带 name 的 <slot> 出口会带有隐含的名字“default”。

父级模板里的所有内容都是在父级作用域中编译的;子模板里的所有内容都是在子作用域中编译的。

 ### 1.默认插槽
    没有名字的插槽就是默认插槽
 	<slot>123</slot>
    <slot name="default">123</slot>
### 2. 具名插槽
    具有名字的插槽
    <slot name="slot2">123</slot>
### 3.插槽填充
    <my-com>hello</my-com>
    内容填充到模板的哪个插槽中?
    指定插槽
    <my-com>
      <template v-slot:default>
        hello
      </template>
      <template v-slot:slot>
        123
      </template>
      <template #slot>
        123
      </template>
    </my-com>
### 插槽声明 {template:`<slot>插槽默认模板</slot>`}
    插槽模板
    ### 1.默认模板
    <slot>插槽默认模板</slot>
    ### 2.自定义模板
    <my-com>
      <template #name>
        插槽自定义模板
      </template>
    </my-com>
  在插槽默认模板中,可以直接访问子组件的数据,可以通过props间接访问父组件的数据
  在插槽自定义模板中,可以直接访问父组件的数据,可以通过插槽属性间接访问子组件的数据
(插槽作用域)

21、vue中的模型mvvm

22、如何让高等于宽的一半,不设置宽的情况下

23、简单说下flex,弹性盒布局

容器属性

  • flex-flow             flex-flow属性是flex-deriction与flex-wrap属性的简写集合,默认属性为row nowrap

  • flex-direction     主轴方向 取值:row(默认) | row-reverse | column | column-reverse

  • flex-wrap           沿主轴的排序处理 取值:nowrap(默认) | wrap | wrap-reverse

  • justify-content   取值:flex-start(默认) | flex-end | center | space-between | space-         around | space-evenly; 用于控制项目在主轴的对齐方式,默认flex-start即左对齐,center 为居中,对应的flex-end为右对齐

  • align-items        取值:flex-start | flex-end | center | baseline | stretch(默认) 。用于控制项目在交叉轴排列方式,默认stretch即如果项目没设置高度,或高度为auto,则占满整个容器 。

  • align-content     取值:flex-start | flex-end | center | space-between | space-around | space-evenly | stretch(默认); 用于控制多行项目的对齐方式,如果项目只有一行则不会起作用 。

元素属性

  • order                取值:默认0,用于决定项目排列顺序,数值越小,项目排列越靠前。

  • flex-grow          取值:默认0,用于决定项目在有剩余空间的情况下是否放大,默认不放大;注意,即便设置了固定宽度,也会放大。

  • flex-shrink        取值:默认1,用于决定项目在空间不足时是否缩小,默认项目都是1,即空间不足时大家一起等比缩小;注意,即便设置了固定宽度,也会缩小。

  • flex-basis         取值:默认auto,用于设置项目宽度,默认auto时,项目会保持默认宽度,或者以width为自身的宽度,但如果设置了flex-basis,权重会比width属性高,因此会覆盖widtn属性。

  • flex                   取值:默认0 1 auto,flex属性是flex-grow,flex-shrink与flex-basis三个属性的简写,用于定义项目放大,缩小与宽度。

  • align-self          取值:auto(默认) | flex-start | flex-end | center | baseline | stretch,表示继承父容器的align-items属性。如果没父元素,则默认stretch。

24、flex是哪几个属性的简写: flex-shrink,flex-grow, flex-basis

取值:默认0 1 auto,flex属性是flex-grow,flex-shrink与flex-basis三个属性的简写,用于定义项目放大,缩小与宽度。

25、水平垂直居中怎么写,能说几种是几种

26、line-heiaht居中的原理

标准定义:两行文字基线之间的距离。

 如图,每一行文字,可看成由上间距、文本内容、下间距构成,根据行高的标准定义,行高等于两条基线之间的距离,即第一行的3-4+上下间距+第二行的1-2+2-3,因为css中每一行的上间距和下间距肯定是相等的,所以代换一下,行高就等于它本身的上间距+下间距+文本高度。因此,我们也可以把行高记为,行高就是一行的高度,这一行的高度中包含了上下两个间距和文本内容本身。

原文链接:css行高(line-height)及文本垂直居中原理_yangyuqingabc的博客-CSDN博客_lineheight垂直居中

27、隐式类型转换,使用==转换的是哪个值,比如: 1==“1”

1.undefined等于null

2.字符串和数字比较时,字符串转数字

3.数字和布尔比较时,布尔转数字

4.字符串和布尔比较时,两者转数字

// ==
undefined == null;    //true
'0' == 0;            //true,字符串转数字
0 == false;           //true,布尔转数字
'0' == false;       //true,两者转数字

28、vuex是啥,请说一下store

Vuex本质上就是一个Vue.js的插件,是用于对复杂应用进行状态管理用的

Vuex和单纯的全局对象有以下两点不同:

    1、Vuex的状态存储是响应式的。当Vue 组件从 Store 中读取状态的时候,若 Store 中的状态发生变化,那么相应的组件也会相应地得到高效更新。
    2、不能直接改变 Store 中的状态。改变Store 中的状态的唯一途径就是显式地提交 mutation

store

每一个Vuex应用的核心就是Store(仓库),我们可以说Store是一个容器,Store里面的状态与单纯的全局变量是不一样的,无法直接改变Store中的状态。想要改变Store中的状态,只有一个办法,显式地提交mutation。

完整的store结构

const store = new Vuex.Store({
  state: {
    // 存放状态
  },
  getters: {
    // state的计算属性
  },
  mutations: {
    // 更改state中状态的逻辑,同步操作
  },
  actions: {
    // 提交mutation,异步操作
  },
  // 如果将store分成一个个的模块的话,则需要用到modules。
   //然后在每一个module中写state, getters, mutations, actions等。
  modules: {
    a: moduleA,
    b: moduleB,
    // ...
  }
});

原文链接:vuex中的Store_stormzi的博客-CSDN博客

29、vue生命周期钩子函数,在数据进行更新之前触发的是什么函数

30、vue3有了解过吗

31、数组去重

https://segmentfault.com/a/1190000016418021

32、element-ui和antv,说说你的看法(因为看你项目中用过)

33、js中this和es6中的this

js中this的指向问题:指向调用的对象,函数定义时是不能确定的

1:函数调用的时候默认指向window,因为所有的全局变量最后都会变成window对象的属性

2:作为对象里面的函数方法,this指向函数的上一级的上下文区域

3:当对象里面的函数调用时变成了函数表达式的话。函数的this指向还是和1的情况一样指向window

4:构造函数中的this指向new出来的对象实例

ES6中this指向

箭头函数中this的指向就是定义时所在的作用域,也就是说箭头函数本身没有this,内部的this就是外层代码块作用域中的this

原文链接:js中this的指向和es6的this指向新变化_蒋百里的博客-CSDN博客

34、基本数据类型和引用数据类型存放的位置

常见的基本数据类型:

  Number、String 、Boolean、Null和Undefine。

        基本数据类型的值直接保存在栈内存中

引用类型数据:

  也就是对象类型Object type,比如:Object 、Array 、Function 、Data等。

  javascript的引用数据类型是保存在堆内存中的对象。

  与其他语言的不同是,你不可以直接访问堆内存空间中的位置和操作堆内存空间。只能操作对象在栈内存中的引用地址。

原文链接:JavaScript中基本数据类型和引用数据类型的区别 - cc_ccc - 博客园

35、执行栈

执行栈,也叫调用栈,具有 LIFO(后进先出)结构,用于存储在代码执行期间创建的所有执行上下文

首次运行JS代码时,会创建一个全局执行上下文并Push到当前的执行栈中。每当发生函数调用,引擎都会为该函数创建一个新的函数执行上下文并Push到当前执行栈的栈顶。

根据执行栈LIFO规则,当栈顶函数运行完成后,其对应的函数执行上下文将会从执行栈中Pop出,上下文控制权将移到当前执行栈的下一个执行上下文。

原文链接:js执行上下文和执行栈 - _wyh - 博客园

0.前置说明:
    0.1 JavaScript 是一门单线程的语言,这意味着它只有一个调用栈,因此,它同一时间只能做一件事。
    0.2 内存堆:这是内存分配发生的地方.
    0.3 调用栈:这是你的代码执行时的地方
1.定义:调用栈是解释器(就像浏览器中的javascript解释器)追踪函数执行流的一种机制。当执行环境中调用了多个函数时,通过这种机制,我们能够追踪到哪个函数正在执行,执行的函数体中又调用了哪个函数。
    1.1 每调用一个函数,解释器就会把该函数添加进调用栈并开始执行。
    1.2 正在调用栈中执行的函数还调用了其它函数,那么新函数也将会被添加进调用栈,一旦这个函数被调用,便会立即执行。
    1.3 当前函数执行完毕后,解释器将其清出调用栈,继续执行当前执行环境下的剩余的代码。
    1.4 当分配的调用栈空间被占满时,会引发“堆栈溢出”。

原文链接:JS 调用栈 - 汪汪汪~~ - 博客园

36、es6新特性,es7-es11说一下

es6新特性:ES6新特性总结 - 嘿!那个姑娘 - 博客园

es7-es11:ES7-ES11新特性汇总_CheryW的博客-CSDN博客_es7新特性

37、js原型和原型链,说一说Object和Function的关系(因为一直proto,会访问到它的原型)

1.JavaScript中,“函数”(方法)也是对象。
2.一切对象都有一个根源。它是Object.prototype。
3.根源之上再没有其他根源。Object.getPrototypeOf(Object.prototype)是null。js中除字面量以外的一切引用对象都来自这个“根源”对象。
4.表达式Object.getPrototypeOf(Function) === Function.prototype的结果是真。这是Function特有的。实际上Function的prototype是一个内置函数,一切函数都派生自这个内置函数,这个内置函数是一个函数工厂。这个内置函数对象的prototype指向“根源”对象。
5.表达式Object.prototype === Object.getPrototypeOf(Function.prototype)的结果是真。说明了Object跟Function二者之间的联系,是通过“根源”对象联系起来的。

Function和Object,既是函数,因为都可以Function()或者Object()这样的方式执行,又是对象,因为可以Function.a = ‘a’,Object.a = 'a’这样赋值。

说它们是函数,是因为他们都是通过上面第4条中说的”内置函数工厂“,派生出来的,因而具备函数的特性。

说他们是对象。是因为他们都是通过上面第1条中的”根源“对象,派生出来的,因此具备对象的特征。

继续说一下,Function.prototype指向”内置函数“。而Object.prototype指向”根源对象“。

因而new Function会产生一个匿名函数,而new Object产生一个plain object。

原文链接:JavaScript原型和原型链 (终)(Object与Function的关系)_刘家军的博客-CSDN博客

38、promise执行顺序

promise执行顺序分并行执行顺序执行

1.Promise.all 并行执行promise

2.顺序执行promise

原文链接:ES6 Promise 并行执行和顺序执行 - 简书

39、事件循环机制

JavaScript的执行机制主要是以下三步

  ① 所有同步任务都在主线程上执行,形成一个执行栈(execution context stack)。

  ② 主线程之外,还存在一个‘任务队列’(task queue)。只要异步任务有了运行结果,就在”任务队列”之中放置一个事件。

  ③ 一旦主线程的栈中的所有同步任务执行完毕,系统就会读取任务队列,选择需要首先执行的任务然后执行。

 原文链接:CSDN

深入理解JavaScript事件循环机制 - ChessZhang - 博客园

40、vuex中双向数据绑定

原理:https://www.jianshu.com/p/e7ebb1500613

get和set

// 在从组件的computed中
computed: {
    user: {
        get() {
          return this.$store.state.user
        },
        set(v) {
          // 使用vuex中的mutations中定义好的方法来改变
          this.$store.commit('USER', v)
        }
    }
}
// 在组件中就可以使用
<input v-modle="user" />

watch

 // 在组件中绑定
<input v-modle="user" />

// 在computed中获取vuex的值
computed: {
  ...mapState( { user: state => state.user } )
}

// 在组件的watch中观测
watch: {
  'user': {
      deep: true,
      handler(value) {
        // 使用vuex中的mutations中定义好的方法来改变
          this.$store.commit('USER', value)
      }
  }
}

 原文链接:vue双向数据绑定vuex中的state - 简书

41、git分支

分支就是科幻电影里面的平行宇宙,当你正在电脑前努力学习Git的时候,另一个你正在另一个平行宇宙里努力学习SVN。

如果两个平行宇宙互不干扰,那对现在的你也没啥影响。不过,在某个时间点,两个平行宇宙合并了,结果,你既学会了Git又学会了SVN!

分支在实际中有什么用呢?假设你准备开发一个新功能,但是需要两周才能完成,第一周你写了50%的代码,如果立刻提交,由于代码还没写完,不完整的代码库会导致别人不能干活了。如果等代码全部写完再一次提交,又存在丢失每天进度的巨大风险。

现在有了分支,就不用怕了。你创建了一个属于你自己的分支,别人看不到,还继续在原来的分支上正常工作,而你在自己的分支上干活,想提交就提交,直到开发完毕后,再一次性合并到原来的分支上,这样,既安全,又不影响别人工作。

Git鼓励大量使用分支:

查看分支:git branch

创建分支:git branch <name>

切换分支:git checkout <name>

创建+切换分支:git checkout -b <name>

合并某分支到当前分支:git merge <name>

删除分支:git branch -d <name>

原文链接:git分支的理解 - matengfei - 博客园

42、字符串去重

JavaScript字符串去重的四种方法_慕课手记

https://segmentfault.com/a/1190000016418021

43、图片懒加载

懒加载原理

一张图片就是一个<img>标签,浏览器是否发起请求图片是根据<img>的src属性,所以实现懒加载的关键就是,在图片没有进入可视区域时,先不给<img>的src赋值,这样浏览器就不会发送请求了,等到图片进入可视区域再给src赋值。


懒加载思路及实现

实现懒加载有四个步骤,如下:
1.加载loading图片
2.判断哪些图片要加载【重点】
3.隐形加载图片
4.替换真图片

原文链接:js实现图片懒加载原理_tomorrownan的博客-CSDN博客_懒加载

44、px、em、rem、rpx 作用和用法详解

px

px像素(Pixel)。相对长度单位。像素px是相对于显示器屏幕分辨率而言的。 PX特点

    IE无法调整那些使用px作为单位的字体大小;
    国外的大部分网站能够调整的原因在于其使用了em或rem作为字体单位;
    Firefox能够调整px和em,rem,但是96%以上的中国网民使用IE浏览器(或内核)。

 em

em是相对长度单位。相对于当前对象内文本的字体尺寸。如当前对行内文本的字体尺寸未被人为设置,则相对于浏览器的默认字体尺寸。 EM特点

    em的值并不是固定的;
    em会继承父级元素的字体大小。

注意:任意浏览器的默认字体高都是16px。所有未经调整的浏览器都符合: 1em=16px。那么12px=0.75em,10px=0.625em。为了简化font-size的换算,需要在css中的body选择器中声明Font-size=62.5%,这就使em值变为 16px*62.5%=10px, 这样12px=1.2em, 10px=1em, 也就是说只需要将你的原来的px数值除以10,然后换上em作为单位就行了。

rem

rem是CSS3新增的一个相对单位(root em,根em),这个单位引起了广泛关注。这个单位与em有什么区别呢?区别在于使用rem为元素设定字体大小时,仍然是相对大小,但相对的只是HTML根元素。这个单位可谓集相对大小和绝对大小的优点于一身,通过它既可以做到只修改根元素就成比例地调整所有字体大小,又可以避免字体大小逐层复合的连锁反应。目前,除了IE8及更早版本外,所有浏览器均已支持rem。

rpx

rpx(responsive pixel): 可以根据屏幕宽度进行自适应。规定屏幕宽为750rpx。如在 iPhone6 上,屏幕宽度为375px,共有750个物理像素,则750rpx = 375px = 750物理像素,1rpx = 0.5px = 1物理像素。
rpx 为小程序中使用的相对单位,用法和rem类似, 1rpx = 屏幕宽度/750 px, 所以在屏幕宽度为750的设计稿中,1rpx = 1px。

原文链接:https://blog.csdn.net/Riven_wn/article/details/80528187?spm=1001.2101.3001.6650.18&utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromBaidu%7Edefault-18.nonecase&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromBaidu%7Edefault-18.nonecase

45、map和object的区别

Key filed

在 Object 中, key 必须是简单数据类型(整数,字符串或者是 symbol),而在 Map 中则可以是 JavaScript 支持的所有数据类型,也就是说可以用一个 Object 来当做一个Map元素的 key。

元素顺序

Map 元素的顺序遵循插入的顺序,而 Object 的则没有这一特性。

继承

Map 继承自 Object 对象。

新建实例

Object 支持几种方法来创建新的实例

Map 仅支持一种构建方法

总结:

  •   JSON 直接支持 Object,但不支持 Map
  •   Map 是纯粹的 hash, 而 Object 还存在一些其他内在逻辑,所以在执行 delete 的时候会有性能问题。所以写入删除密集的情况应该使用 Map。
  •   Map 会按照插入顺序保持元素的顺序,而Object做不到。
  •   Map 在存储大量元素的时候性能表现更好,特别是在代码执行时不能确定 key 的类型的情况。

原文链接:JavaScript Map 和 Object 的区别 - ysx_小鱼 - 博客园

46、null和undefined的区别

一、相同点:

1、都是原始类型的值,且保存在栈中变量本地
2、进行条件判断时,两者都是false

二、不同点

1、null是js的关键字,表示空值;undefined不是js的关键字,它是一个全局变量
2、null是Object的一个特殊值,如果一个Object为null,表示这个对象不是有效对象,null是一个不存在的对象的占位符;undefined是Globel的一个属性

原文链接:js中的null和undefined区别_王美玲-CSDN博客_js null和undefined 区别

47、URL输入到页面加载完成发生了什么

从前端的角度出发,我觉得首先回答必须包括以下几个基本的点:

1、浏览器的地址栏输入URL并按下回车。
2、浏览器查找当前URL是否存在缓存,并比较缓存是否过期。
3、DNS解析URL对应的IP。
4、根据IP建立TCP连接(三次握手)。
5、HTTP发起请求。
6、服务器处理请求,浏览器接收HTTP响应。
7、渲染页面,构建DOM树。
8、关闭TCP连接(四次挥手)。

原文链接:从输入url到页面加载完成发生了什么? - 简书

48、for of 和 for in 的区别

for in 的特点

结合上面的两个例子,分析得出:

        for ... in 循环返回的值都是数据结构的 键值名。

        遍历对象返回的对象的key值,遍历数组返回的数组的下标(key)。

        for ... in 循环不仅可以遍历数字键名,还会遍历原型上的值和手动添加的其他键。

        特别情况下, for ... in 循环会以看起来任意的顺序遍历键名。

for of 特点

        for of 循环用来获取一对键值对中的值,而 for in 获取的是 键名。

        一个数据结构只要部署了 Symbol.iterator 属性, 就被视为具有 iterator接口, 就可以使用 for of循环。

        没有 Symbol.iterator这个属性,所以使用 for of会报 obj is not iterable。

        for of 不同与 forEach, 它可以与 break、continue和return 配合使用,也就是说 for of 循环可以随时退出循环。

        提供了遍历所有数据结构的统一接口。

总结一句: for in 循环特别适合遍历对象,for of 更适合遍历数组。

原文链接:百度前端面试题:for in 和 for of的区别详解以及为for in的输出顺序 - 知乎

49、forEach 和 map 的区别

一、相同点:

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

forEach和map方法里每次执行匿名函数都支持3个参数,参数分别是item(当前每一项)、index(索引值)、arr(原数组)

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

只能遍历数组

二、区别:

1.forEach()

 没有返回值。

2.map() 

有返回值,可以return 出来。

三、兼容写法:

不管是forEach还是map在IE6-8下都不兼容(不兼容的情况下在Array.prototype上没有这两个方法)

原文链接:forEach()和map()的区别_xif3681的博客-CSDN博客_foreach和map的区别

50、vue路由传参的几种方式

https://blog.csdn.net/m0_37843876/article/details/108196266

51、什么是AMD模块化规范

AMD是"Asynchronous Module Definition"的缩写,意思就是"异步模块定义"。它采用异步方式加载模块,模块的加载不影响它后面语句的运行。所有依赖这个模块的语句,都定义在一个回调函数中,等到加载完成之后,这个回调函数才会运行。

AMD也采用require()语句加载模块,但是不同于CommonJS,它要求两个参数:

  require([module], callback);

第一个参数[module],是一个数组,里面的成员就是要加载的模块;第二个参数callback,则是加载成功之后的回调函数。如果将前面的代码改写成AMD形式,就是下面这样:

  require(['math'], function (math) {

    math.add(2, 3);

  });

math.add()与math模块加载不是同步的,浏览器不会发生假死。所以很显然,AMD比较适合浏览器环境。

原文链接:https://www.ruanyifeng.com/blog/2012/10/asynchronous_module_definition.html

52、箭头函数和普通函数的区别

1.书写上的区别

  箭头函数比普通函数更加的简洁,而且在一定程度上可以简写,比如,括号里面只有一个参数,括号可以省略, 另外如果函数体中只有一行代码,花括号也可以省略。

2.参数上的区别

  普通函数的参数是arguments,而箭头函数的的是args

3.this指向的不同

  箭头函数的this指向上层函数作用域的this对象,如果没有上层函数作用域,则指向顶部this(在浏览器中顶部this则是window)。普通函数的this指向该函数的调用者。
  call, apply, bind会改变普通函数的this,但不会改变箭头函数的this

4.原型和构造函数的问题

  箭头函数不能使用new生成实例,因为箭头函数没有prototype,而construct在prototype里面

5.对es6使用的限制

  箭头函数内不能用yield且不能用作Generator函数,而普通函数可以。


原文链接:https://www.jianshu.com/p/844e293d90a7

  • 0
    点赞
  • 1
    收藏
  • 打赏
    打赏
  • 0
    评论

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

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
©️2022 CSDN 皮肤主题:深蓝海洋 设计师:CSDN官方博客 返回首页
评论

打赏作者

魔尊抱抱

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

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

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

打赏作者

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

抵扣说明:

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

余额充值