前端面试题(持续更新中)

【1】null和undefined的区别

同:

1.都是js的基本类型,保存在栈中,表示“无、没有”的意思。

2.if语句中的null和undefined都是false。

var a = undefined
var b = null
if (!a) {
    console.log('undefined is false');
}
if (!b) {
    console.log('null is false');
}

a == b  //true

异:

1.null表示空值,一个变量将来可能指向一个对象;一个不存在的dom节点就是null,转为数值是0。

undefined表示变量声明但没有赋值或者不存在的对象属性值,转为数值是NaN。

2.典型用法:

null表示"没有对象",即该处不应该有值。典型用法是:

(1) 作为函数的参数,表示该函数的参数不是对象。

(2) 作为对象原型链的终点。

undefined表示"缺少值",就是此处应该有一个值,但是还没有定义。典型用法是:

(1)变量被声明了,但没有赋值时,就等于undefined。

(2) 调用函数时,应该提供的参数没有提供,该参数等于undefined。

(3)对象没有赋值的属性,该属性的值为undefined。

(4)函数没有返回值时,默认返回undefined。

【2】什么是w3c标准?理解下

w3c是万维网联盟标准,它不是指某一个标准,而是指一系列标准的集合。

w3c标准可分为结构、表现、行为,三部分独立为模块化。结构化标准语言主要包括XML和XHTML;表现标准语言主要指CSS;行为标准主要包括对象模型ECMAScript。【jQuery不符合w3c标准】

1.需要声明(DOCTYPE)

2. 需要定义语言编码

<meta http-equiv=“Content-Type” content="text/html" charset="utf-8" />

3.JavaScript定义

js必须要用<script language="javascript" type="text/javascript">来定义开头,而不是原来的<script language="javascript">或干脆直接<script>

4.CSS定义

CSS必须要用<style type=“text/css”>开头来定义,而不是原来的直接<style>;也不建议直接写在内容代码中的行内样式。

5.不要在注释内容中使用’’–’’

“–”只能发生在XHTML注释的开头和结束,也就是说,在内容中不能有-

例如下面的代码是无效的:
<!--这里是注释-----------这里是注释-->
 
正确的应用等号或者空格替换内部的虚线:
<!--这里是注释============这里是注释-->

6.所有标签的元素和属性的名字都必须使用小写

与HTML不一样,XHTML对大小写是敏感的,

和是不同的标签

7.所有的属性必须用引号""括起来

在HTML中,可以不需要给属性值加引号,但是在XHTML中,它们必须要加引号

例如:<height=80>必须修改为:<height=“80”>、<alt=“say'hello'”>修改为<alt="say&apos;hello&apos;">

8. 把所有特殊符号用编码表示,例如:小于号(<)用&lt;表示。

9.所有属性必须有属性值

XHTML规定所有属性都必须有个值,没有值就是重复本身

// 不规范
<td nowrap><input type="checkbox" name="shirt" value="medium" checked>
  
// 规范做法
<td nowrap="nowrap"><input type="checkbox" name="shirt" value="medium" checked="checked" />

tips:

1、标签规范可以提高搜索引擎对页面的抓取效率,对SEO(搜索引擎优化)很有帮助

2、尽量使用外链css样式表和js脚本:结构、表现和行为分为三块,符合规范,同时提高页面渲染速度,提高用户的体验。

3、样式尽量少用行内样式表,使结构与表现分离,标签的id和class等属性命名要做到见文知义,标签越少,加载越快,用户体验提高,代码维护简单,便于改版

【3】虚拟dom树的理解(参考文章虚拟DOM的实现原理与优缺点_虚拟dom的优缺点_z逍遥的博客-CSDN博客

虚拟DOM就是为了解决浏览器性能问题而被设计出来的。如前,若一次操作中有10次更新DOM的动作,虚拟DOM不会立即操作DOM,而是将这10次更新的diff内容保存到本地一个JS对象中,最终将这个JS对象一次性attch到DOM树上,再进行后续操作,避免大量无谓的计算量。所以,用JS对象模拟DOM节点的好处是,页面的更新可以先全部反映在JS对象(虚拟DOM)上,操作内存中的JS对象的速度显然要更快,等更新完成后,再将最终的JS对象映射成真实的DOM,交由浏览器去绘制。

虚拟dom本质上是js对象,是对真实dom的抽象。状态变化时,记录新树和旧树的差异,最后把差异更新到真实dom中。

虚拟dom的作用:①解决代码冗余,耦合度高且难维护的问题;②优化前端性能,提高渲染效率。

1.patch函数

patch函数的执行分为两个阶段,两次传递的参数都是两个

第一阶段为虚拟dom的第一次渲染,传递的两个参数分别是放真实DOM的container和生成的vnode,此时patch函数的作用是用来将初次生成的真实DOM结构挂载到指定的container上面。

第二阶段传递的两个参数分别为vnode和newVnode,此时patch函数的作用是使用diff算法对比两个参数的差异,进而更新参数变化的DOM节点;

可以发发现h函数和patch函数在cnabbdom中实现vdom到真实DOM的转化起到了至关重要的作用,那么还有一个很重要的环节,patch函数中是怎么样实现对比两个vnode从而实现对真实DOM的更新的呢,这里还要提一下snabbdom的另外一个核心算法,即diff算法。

2.diff算法

把树形结构按照层级分解,只比较同级元素,不同层级的节点只有创建和删除操作。

3.虚拟dom的优缺点:

优点:

保证性能下限: 虚拟DOM可以经过diff找出最小差异,然后批量进行patch,这种操作虽然比不上手动优化,但是比起粗暴的DOM操作性能要好很多,因此虚拟DOM可以保证性能下限

无需手动操作DOM: 虚拟DOM的diff和patch都是在一次更新中自动进行的,我们无需手动操作DOM,极大提高开发效率

跨平台: 虚拟DOM本质上是JavaScript对象,而DOM与平台强相关,相比之下虚拟DOM可以进行更方便地跨平台操作,例如服务器渲染、移动端开发等等

缺点:

无法进行极致优化: 在一些性能要求极高的应用中虚拟DOM无法进行针对性的极致优化,比如vscode采用直接手动操作DOM的方式进行极端的性能优化。

【4】浏览器内核

1.IE --> Trident内核,也就是俗称的IE内核

2.Chrome --> 以前是Webkit内核,现在是Blink内核

3.Firefox --> Gecko内核

4.Opera -->Blink内核

5.Safari --> Webkit内核

【5】JavaScript的基本规范,写几条

1.变量和函数为小驼峰法标识

2.通常运算符 ( = + - * / ) 前后需要添加空格

3.通常使用 4 个空格符号来缩进代码块

4.一条语句通常以分号作为结束符

5.常量 (如 PI) 为大写

6.为了便于阅读每行字符建议小于数 80 个,如果一个 JavaScript 语句超过了 80 个字符,建议在 运算符或者逗号后换行。

【6】window对象和document对象的区别(参考文章JS中的window对象和document对象是什么?有什么区别?_window对象和document对象的区别_高明懿大可爱的博客-CSDN博客

一、指代不同

1、document对象:代表给定浏览器窗口中的HTML文档,document是window的一个对象属bai性。

2、window对象:表示浏览器中打开的窗口。

二、作用不同

1、document对象:使用document对象可以对HTML文档进行检查、修改或添加内容,并处理该文档内部的事件。

2、window对象:浏览器会为HTML文档创建一个window对象,并未每个框架创建一个额外的window对象。

三、使用方式不同:

1、document对象:在Web页面上,document对象可通过window对象的document属性引用,或者直接引用。

2、window对象:没有应用于window对象的公开标准,不过所有浏览器都支持该对象。

【7】BOM和DOM的区别(参考文章DOM和BOM的区别_bom和dom的区别_学学学无止境的博客-CSDN博客

js是三部分组成:

ECMAScript:描述了js的语法和基本对象;

BOM(浏览器对象):与浏览器交互的方法和对象;

DOM(文档对象模型):定义了梳理网页的内容和接口;

DOM是W3C的标准(所有浏览器公共遵守的标准);BOM是各个浏览器厂商根据DOM在各自浏览器上的实现(浏览器不同,具体的表现形式也有差异,ie更是风格迥异)

1.DOM(document也是BOM的window的子对象;)

文档对象模型,它指的是把文档当做一个对象来对待,这个对象主要定义了处理网页的内容和接口。

2.BOM( location、navigato、document)

浏览器对象模型,它指的是把浏览器当做一个对象来对待,这个对象主要定义了浏览器进行交互的方法和接口。

BOM的核心是window,而window具有双重角色,它既是js访问浏览器窗口的一个接口,又是一个全局对象,这就代表网页中定义的任何对象、变量和函数都是作为全局对象的一个属性或方法存在。

【8】document.write和innerHTML的区别(参考文章document.write和innerHTML的区别_innerhtml和document.write区别_小怪兽_v的博客-CSDN博客

document.write是直接写入到页面的内容流,如果在写之前没有调用document.open, 浏览器会自动调用open。每次写完关闭之后重新调用该函数,会导致页面被重写

innerHTML则是DOM页面元素的一个属性,代表该元素的html内容。(可获取内容 、修改内容)可以精确到某一个具体的元素来进行更改。

innerHTML很多情况下都优于document.write,其原因在于其允许更精确的控制要刷新页面的那一个部分。

write是方法,会全部重写网页内容。

而innerHTML则是属性,而且是定向改写。

【9】计算属性computed和watch的区别

computed的使用场景:监听其他值的变化,经过逻辑处理得到新属性值,可以监听多个值来完成一个值的计算,例如算出几个数的总和。

watch的使用场景:它可以监听这个值的新值和旧值,然后根据这个值的变化做出逻辑处理,可以监听一个值完成多个计算,例如监听A值改变相应的改变B值和C值。

计算属性computed是依赖其他属性得到一个新属性,基于data中声明过或者父组件传递的 props 中的数据通过计算得到的一个新值,这个新值只会根据已知值的变化而变化,换句话说,这个属性依赖其他属性,由其他属性计算而来的。

特点:

computed,支持缓存,只有依赖数据发生改变,才会重新进行计算(缓存功能:多次调用也不会重新计算)

● computed 不支持异步,当 computed 内有异步操作时无效

● 如果一个属性是由其他属性计算而来的,这个属性依赖其他属性,是一个多对一或者一对一(可以依赖一个或多个属性的值),一般用 computed

● 如果 computed 属性属性值是函数,那么默认会走 get() ;函数的返回值就是属性的属性值;在 computed 中的,属性都有一个 get() 和一个 set(),当数据变化时,调用 set() (computed里属性值变化,调用此属性的set())。

● computed的属性值用法和data、prop相同,且不能与其属性冲突

watch,主要用来监听某些特定数据的变化,从而进行某些具体的业务逻辑操作,可以看作是 computed 和 methods 的结合体;

● 可以监听的数据来源:data,props,computed内的数据;

● watch支持异步;

● 不支持缓存,监听的数据改变,直接会触发相应的操作;

● 监听函数有两个参数,第一个是最新的值,第二个参数是输入之前的值,顺序是新值,旧值,如果只填一个值,则为新值。

【10】父子组件的生命周期(参考文章Vue——父子组件的生命周期(执行顺序)_默默花上开的博客-CSDN博客

一个组件的生命周期:

  • 挂载(初始化相关属性)
  1. beforeCreate
  2. created
  3. beforeMount
  4. mounted
  • 更新(元素或组件的变更操作)
  1. beforeUpdate
  2. updated
  • 销毁(销毁相关属性)
    • beforeDestroy
    • destroyed

一个完整的父子组件生命周期:

父beforeCreate -> 父created -> 父beforeMount -> 子beforeCreate -> 子created -> 子beforeMount -> 子mounted -> 父mounted->父beforeUpdate->子beforeUpdate->子updated->父updated->父beforeDestroy->子beforeDestroy->子destroyed->父destroyed

父:

<template>
  <div>
    <input type="text" name="text" id="" v-model="text" />
    <button id="destroy" @click="handle">点击</button>
    <livechidren :text="text"></livechidren>
  </div>
</template>

<script>
import livechidren from "./livechidren.vue";
export default {
  components: { livechidren },
  data() {
    return {
      text: "",
    };
  },
  methods: {
    handle() {
      this.$destroy();
    },
  },
  beforeCreate() {
    console.log("父组件————beforeCreate...");
  },
  created() {
    console.log("父组件————create...");
  },
  beforeMount() {
    console.log("父组件————beforeMount...");
  },
  mounted() {
    console.log("父组件————mounted...");
  },
  beforeUpdate() {
    console.log("父组件————beforeUpdate...");
  },
  updated() {
    console.log("父组件————updated...");
  },
  beforeDestroy() {
    console.log("父组件————beforeDestroy...");
  },
  destroyed() {
    console.log("父组件————destroyed...");
  },
};
</script>

<style>
#destroy{
    width: 80px;
    height: 30px;
    border: none;
    background: rgb(209, 250, 236);
}
</style>

子:

<template>
  <div>{{text}}</div>
</template>

<script>
export default {
  data() {
    return {};
  },
  props:{
      text: {
          type: String,
      }
  },
  beforeCreate() {
    console.log("子组件————beforeCreate...");
  },
  created() {
    console.log("子组件————create...");
  },
  beforeMount() {
    console.log("子组件————beforeMount...");
  },
  mounted() {
    console.log("子组件————mounted...");
  },
  beforeUpdate() {
    console.log("子组件————beforeUpdate...");
  },
  updated() {
    console.log("子组件————updated...");
  },
  beforeDestroy() {
    console.log("子组件————beforeDestroy...");
  },
  destroyed() {
    console.log("子组件————destroyed...");
  },
};
</script>

<style>
</style>

结果如下:

【11】什么是闭包?产生原因?

闭包是指能够读取其它函数内部变量的函数。创建闭包的常见方式,就是在一个函数内部创建另一个函数。可以把闭包简单理解成  ‘定义在一个函数内部的函数’。

闭包的产生原因:变量作用域的问题(全局变量和局部变量)

由于变量的作用域的原因,函数内部能读取全局变量,函数外部无法读取函数内部的局部变量,为了在函数外部读取局部变量,所以就有了闭包。

闭包的作用:

1.访问其他函数内部变量

2.让这些变量的值始终保存在内存中,保护变量不被内存回收机制回收

3.避免全局变量被污染 方便调用上下文的局部变量,加强封装性

闭包的缺点:

闭包长期占用内存,内存消耗很大,可能导致内存泄露

【12】防止冒泡

1.event.stopPropagation();

2.return false;

3.时间修饰符.stop

【13】v-if和v-for的优先级

当vue处理指令时,v-for比v-if具有更高的优先级;但是在vue3中,v-if具有比v-for更高的优先级。

注意事项:

1.v-if和v-for同时用在同一个元素上,会带来性能上的浪费,每次渲染都会先循环在进行条件判断。

2.如果避免v-if和v-for同时作用在容一个元素上,可以在元素外面套一层写v-if。

3.可以通过计算属性过滤掉那些不需要显示的项

【14】vue的生命周期有哪些(参考文章⑥ Vue的生命周期_vue生命周期_CRMEB的博客-CSDN博客

简单来说:在 Vue 从创建实例到最终完全消亡的过程中,会执行一系列的方法,用于对应当前 Vue 的状态,这些方法我们叫它:生命周期钩子!

vm的生命周期:

将要创建-->调用beforeCreate函数;

创建完毕-->调用created函数;

将要挂载-->调用beforeMount函数;

挂载完毕-->调用mounted函数;----重要的钩子

将要更新-->调用beforeUpdate函数;

更新完毕-->调用updated函数;

将要销毁-->调用beforeDestroy函数;----重要的钩子

销毁完毕-->调用destroyed函数;

【15】mvc的理解

MVC所有通信都是单向的,提交一次反馈一次,通信一次相互制约。MVC允许在不改变视图的情况下改变视图对用户输入的响应方式,用户对View的操作交给了Controller处理,在Controller中响应View的事件调用Model的接口对数据进行操作,一旦Model发生变化便通知相关视图进行更新。

视图(View):用户界面。(传送指令到 Controller)

控制器(Controller):业务逻辑(完成业务逻辑后,要求 Model 改变状态)

模型(Model):数据保存(将新的数据发送到 View,用户得到反)

【16】mvvm的理解

mvvm前后端分离:Model用纯js对象表示,View负责显示。ViewModel负责把view和model关联起来,把model的数据同步到view,还负责吧view修改的同步到model。

1.各部分之间的通信,都是双向的。

2.View 与 Model 不发生联系,都通过ViewModel传递。

model:服务器的业务逻辑操作

view:用户界面

ViewModel:核心枢纽

底层v-model的原理是事件绑定和属性绑定,事件绑定不是click,而是v-on:input事件绑定,这是input标准事件。

mvvm中的vm是控制逻辑

【17】mvc和mvvm的区别

1.MVC是单向的,而MVVM是双向的,并且是自动的,也就是数据发生变化自动同步视图,视图发生变化自动同步数据。

2.解决了 MVC 中大量的 DOM 操作使页面渲染性能降低,加载速度变慢,影响用户体验等问题。

3.在数据频繁更新的时候,采用了虚拟DOM,减少过度渲染,提高性能。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值