2021Web前端面试必问

本文详细探讨了前端开发中的跨域问题及其解决方案,包括JSONP、CORS、postMessage、WebSocket和代理服务器等。同时,介绍了同源策略、前后端通信方式、浏览器的本地存储机制、以及Vue组件通信和性能优化策略。此外,还涵盖了ES6的特性、Vue的双向绑定原理、DOM操作与内存管理、以及HTTP与HTTPS的区别。最后,讨论了单页面应用(SPA)的工作原理和优缺点。
摘要由CSDN通过智能技术生成

跨域如何解决

解决方案:

  1. jsonp(利用script标签没有跨域限制的漏洞实现。缺点:只支持GET请求)
  2. CORS(设置Access-Control-Allow-Origin:指定可访问资源的域名)
  3. postMessage(message, targetOrigin, [transfer])(HTML5新增API 用于多窗口消息、页面内嵌iframe消息传递),通过onmessage监听 传递过来的数据
  4. Websocket是HTML5的一个持久化的协议,它实现了浏览器与服务器的全双工通信,同时也是跨域的一种解决方案。
  5. Node中间件代理
  6. Nginx反向代理
  7. 各种嵌套iframe的方式,不常用。
  8. 日常工作中用的最多的跨域方案是CORS和Nginx反向代理

什么是同源策略

一个域下的js脚本未经允许的情况下,不能访问另一个域下的内容。通常判断跨域的依据是协议、域名、端口号是否相同,不同则跨域。同源策略是对js脚本的一种限制,并不是对浏览器的限制,像img,script脚本请求不会有跨域限制。

前后端如何通信

ajax:短连接

websocket:长连接,双向的

Form表单(最原始的)

浏览器的本地存储?各自优劣如何?

  1. 浏览器的本地存储主要分为Cookie、WebStorage和IndexDB,其中WebStorage又可以分为localStorage和sessionStorage.

  2. 共同点:都是保存在浏览器端、且同源的

  3. 不同点:

    1. cookie数据始终在同源的http请求中携带(即使不需要),即cookie在浏览器和服务器间来回传递。cookie数据还有路径(path)的概念,可以限制cookie只属于某个路径下sessionStoragelocalStorage不会自动把数据发送给服务器,仅在本地保存。

    2. 存储大小限制也不同,

    3. cookie数据不能超过4K,sessionStorage和localStorage可以达到5M

    4. sessionStorage:仅在当前浏览器窗口关闭之前有效;

    5. localStorage:始终有效,窗口或浏览器关闭也一直保存,本地存储,因此用作持久数据;

    6. cookie:只在设置的cookie过期时间之前有效,即使窗口关闭或浏览器关闭

    7. 作用域不同

    8. sessionStorage:不在不同的浏览器窗口中共享,即使是同一个页面;

    9. localstorage:在所有同源窗口中都是共享的;也就是说只要浏览器不关闭,数据仍然存在

    10. cookie: 也是在所有同源窗口中都是共享的.也就是说只要浏览器不关闭,数据仍然存在

token原理

客户端输入用户名和密码,将这次请求提交到服务器,服务器根据用户这次请求验证用户是否存在,验证成功之后,服务器端会向客户端返回一个唯一的token值,客户端需要把服务器端返回的token值记录到客户端本地,之后客户端要请求服务器端的接口就必须要携带token,才能正常的进行操作,因为token是保证你登录成功之后的唯一身份令牌。

(我们用的token,他的机制叫做json web token(简称jwt),前端调用登录接口,传入用户名,密码,后端校验,如果正确就通过jwt生成token,返回给前端,一般是保存到storage或者是cookie里面,每次调用需要依赖登陆的接口的时候携带上token,后台以此判断用户的登陆状态。因为token是后台加密生成的,一般很难破解,所以基本不会存在伪造token的风险。)

说一说你对闭包的理解

闭包是指有权访问另一个函数作用域中的变量的函数

当函数可以记住并访问所在的词法作用域时,就产生了闭包,即使函数是在当前词法作用域之外执行

  • 闭包用途:
    1. 能够访问函数定义时所在的词法作用域(阻止其被回收)
    2. 私有化变量
    3. 模拟块级作用域
    4. 创建模块
  • 闭包缺点:会导致函数的变量一直保存在内存中,过多的闭包可能会导致内存泄漏

vue组件的通信方式

父子组件通信

父->子props,子->父 $on、$emit` 获取父子组件实例 parent、childrenRef 获取实例的方式调用组件的属性或者方法 Provide、inject` 官方不推荐使用,但是写组件库时很常用

兄弟组件通信

Event Bus 实现跨组件通信 Vue.prototype.$bus = new Vue() Vuex

跨级组件通信

$attrs、$listeners Provide、inject

组件化与模块化

        模块化:从代码的逻辑操作划分的,将不同功能的代码逻辑划分成不同的模块,方便代码的分层开发,方便后期对于代码的维护,确保了每个功能模块功能单一

        组件化:从UI设计角度出发划分的,前端组件化,为了方便UI组件重复使用,相当于在模块化的基础上添加了页面结构

git常用的命令以及与其他版本控制器的区别

常用命令:

 git remote -v 查看远程仓库地址	 
 git remote rm origin 删除当前远程仓库地址
 git remote add origin url  添加新的远程仓库地址
 git add 把要提交的所有修改放到暂存区
 git commit -m ' '  一次性把暂存区的所有修改提交到分支
 rm -rf .git/ 删除git
 git push origin master -u 将文件推送到远程仓库
 git diff 比较的是工作区与资源库的不同
 git diff --staged(比较的是暂存区和资源库的不同)
 git log 查看提交日志(显示从最近到最远的日志)
 git log --oneline 查看提交日志 在一行显示
 git reset --soft HEAD~ 回到暂存区
 git restore --staged 还原
 git revert 恢复文件的历史版本
 git checkout --<file> 撤销修改
 git stash 保存,恢复,删除工作状态
 git branch  dev 创建分支 /git branch 查看当前分支
 git checkout dev 切换分支
 git checkout -b dev 创建并切换(相当于上面两条命令)
 git merge dev 用于合并指定分支到当前分支
 git switch master 切换分支 
 git switch -c dev 创建并切换到新的分支
 git branch -m dev-3 dev-4 重命名
 git branch -d dev-4 删除分支
 git push origin dev 相当于在远程建立一个新的dev分支
 git pull 拉取(每次提交前先pull一下)
 git push 推送

GIT与SVN的区别:

SVN是集中式版本控制系统,版本库是集中放在中央服务器的,而工作的时候,用的都是自己的电脑,所以首先要从中央服务器得到最新的版本,然后工作,完成工作后,需要把自己做完的活推送到中央服务器。集中式版本控制系统是必须联网才能工作,对网络带宽要求较高。

Git是分布式版本控制系统,每个人的电脑就是一个完整的版本库,工作的时候不需要联网了,因为版本都在自己电脑上。协同的方法是这样的:比如说自己在电脑上改了文件A,其他人也在电脑上改了文件A,这时,你们俩之间只需把各自的修改推送给对方,就可以互相看到对方的修改了。Git可以直接看到更新了哪些代码和文件!

前端性能优化的几种方式

浏览器缓存

防抖、节流

资源懒加载、预加载

开启Nginx gzip压缩

三个方面来说明前端性能优化

webpack优化与开启gzip压缩

  • babel-loader用include或exclude来帮我们避免不必要的转译,不转译node_moudules中的js文件,其次在缓存当前转译的js文件,设置loader:'babel-loader?cacheDirectory=true'

  • 文件采用按需加载等

  • 具体的做法非常简单,只需要你在你的request headers中加上这么一句:accepc-encoding:gzip

  • 图片优化,采用svg图片或字体图标

  • 浏览器缓存机制,它又分为强缓存和协商缓存

本地存储——从Cookie到Web Storage、IndexeDB

  • 说明一下sessionStorage和localStorage还有cookie的区别和优缺点

代码优化

  • 事件代理

  • 事件的节流和防抖

  • 页面的回流和重绘

  • EventLoop事件循环机制

  • 代码优化等

ES5的继承和ES6的继承有什么区别

ES5的继承是通过prototype或构造函数机制来实现。ES5的继承实质上是先创建子类的实例对象,然后再将父类的方法添加到this上(Parent.apply(this))。

ES6的继承机制完全不同,实质上是先创建父类的实例对象this(所以必须先调用父类的super()方法),然后再用子类的构造函数修改this

具体的:ES6通过class关键字定义类,里面有构造方法,类之间通过extends关键字实现继承。子类必须在constructor方法中调用super方法,否则新建实例报错。因为子类没有自己的this对象,而是继承了父类的this对象,然后对其进行加工。如果不调用super方法,子类得不到this对象。

ps:super关键字指代父类的实例,即父类的this对象。在子类构造函数中,调用super后,才可使用this关键字,否则报错。

fetch发送2次请求的原因

fetch发送post请求的时候,总是发送2次,第一次状态码是204,第二次才成功?

原因很简单,因为你用fetch的post请求的时候,导致fetch 第一次发送了一个Options请求,询问服务器是否支持修改的请求头,如果服务器支持,则在第二次中发送真正的请求。

为什么虚拟dom会提高性能

虚拟dom相当于在js和真实dom中间加了一个缓存,利用dom diff算法避免了没有必要的dom操作,从而提高性能。

具体实现步骤如下:

用 JavaScript 对象结构表示 DOM 树的结构;然后用这个树构建一个真正的 DOM 树,插到文档当中

当状态变更的时候,重新构造一棵新的对象树。然后用新的树和旧的树进行比较,记录两棵树差异

把2所记录的差异应用到步骤1所构建的真正的DOM树上,视图就更新了。

http和https的区别?

http传输的数据都是未加密的,也就是明文的,网景公司设置了SSL协议来对http协议传输的数据

进行加密处理,简单来说https协议是由http和ssl协议构建的可进行加密传输和身份认证的网络协

议,比http协议的安全性更高。主要的区别如下:

  • Https协议需要ca证书,费用较高。

  • http是超文本传输协议,信息是明文传输,https则是具有安全性的ssl加密传输协议。

  • 使用不同的链接方式,端口也不同,一般而言,http协议的端口为80,https的端口为443

  • http的连接很简单,是无状态的;HTTPS协议是由SSL+HTTP协议构建的可进行加密传输、身份认证的网络协议,比http协议安全。

简单讲一讲ES6的一些新特性

  1. ES6 在变量的声明和定义方面增加了 let、const 声明变量,有局部变量的概念,赋值中有比较吸引人的解构赋值,同时 ES6 对字符串、 数组、正则、对象、函数等拓展了一 些方法,如字符串方面的模板字符串、函数方面的默认参数、对象方面属性的简洁表达 方式,ES6 也 引入了新的数据类型 symbol,新的数据结构 set 和 map,symbol 可以通过typeof 检测出来,为解决异步回调问题,引入了 promise 和 generator,还有最为吸引人的是实现了 Class 和模块,通过 Class 可以更好的面向对象编程,使用模块加载方便模块化编 程,当然考虑到 浏览器兼容性,我们在实际开发中需要使用 babel 进行编译
  2. 重要的特性:
    1. 块级作用域:ES5 只有全局作用域和函数作用域,块级作用域的好处是不再需要立即执行的函数表达式,循环体中的闭包不再有问题 rest 参数:用于获取函数的多余参数,这样就不需要使用 arguments 对象了,
    2. promise:一种异步编程的解决方案,比传统的解决方案回调函数和事件更合理强大
    3. 模块化:其模块功能主要有两个命令构成,export 和 import,export 命令用于规定模块的 对外接口,import 命令用于输入其他模块提供的功能。

vue的双向绑定原理

Vue 数据双向绑定是通过数据劫持结合发布者-订阅者模式的方式来实现的。利用了
Object.defineProperty() 这个方法重新定义了对象获取属性值(get)和设置属性值(set)。

vue指令和vue事件

vue指令:

v-if:判断是否隐藏;
v-for:数据循环;
v-bind:class:绑定一个属性;
v-model:实现双向绑定 
vue事件:
.stop 阻止冒泡
.prevent 阻止默认事件
.capture 添加事件侦听器时使用事件捕获模式
.once 事件只触发一次
.self 只有点击当前元素本身时才会触发回调

路由传参

  1. 使用query传参的时候,name,path都可以引入,但使用params传参的时候只能使用name进行引入。接收参数都是类似的,分别是this.$route.query.name和this.$route.params.name
  2. 进行路由跳转的时候,我们使用this.$router.push(‘路径')。
  3. query更加类似于我们ajax中get传参,params则类似于post,前者在浏览器地址栏中显示参数,后者则不显示。

v-if和v-show有什么区别

  1. v-if和v-show都可以显示和隐藏一个元素,但有本质区别
  2. v-if是惰性的,只是值为false就不会加载对应元素,为true才动态加载对应元素
  3. v-show:是无论为true和为false都会加载对应html代码,为false时用display:none隐藏不在页面显示,为true时页面上用display:block显示其效果
     适用场景:切换频繁的场合用v-show,切换不频繁的场合用v-if (比如权限验证)

v-if和v-for的优先级

当 v-if 与 v-for 一起使用时,v-for 具有比 v-if 更高的优先级。v-for 还支持一个可选的第二个参数为当前项的索引 。

如何使用代码让360浏览器使用极速模式,而不是兼容模式

若页面需默认用极速核,增加标签:<meta name="renderer" content="webkit">

computed和watch的区别

  • computed是计算属性,具有缓存性。
    当页面中有某些数据依赖其他数据进行变动的时候,可以使用计算属性computed
    用于依赖发生变化时,触发属性重新计算。
    Computed本质是一个具备缓存的watcher,依赖的属性发生变化就会更新视图。 适用于计算比较消耗性能的计算场景。
  • watch更多的是「观察」的作用,类似于某些数据的监听回调,用于观察props,$emit或者本组件的值,当数据变化时来执行回调进行后续操作。
    无缓存性,页面重新渲染时值不变化也会执行。
    Watch没有缓存性,更多的是观察的作用,可以监听某些数据执行回调。当我们需要深度监听对象中的属性时,可以打开deep:true选项,这样便会对对象中的每一项进行监听。这样会带来性能问题,优化的话可以使用字符串形式监听,如果没有写到组件中,不要忘记使用unWatch手动注销。
  • 应用场景:
    当我们要进行数值计算,而且依赖于其他数据,那么把这个数据设计为computed。
    如果你需要在某个数据变化时做一些事情,使用watch来观察这个数据变化。

DOM的属性和方法

js原生dom的操作方法有:

  1. 查找:getElementById,getElementsByTagName,querySelector
  2. 插入:appendChild,insertBefore
  3. 删除:removeChild
  4. 克隆:cloneNode
  5. 设置和获取属性:setAttribute('属性名','值'),getAttribute('属性名')

DOM操作中哪些会造成内存泄露

内存泄漏:指一块被分配的内存既不能使用,又不能回收,直到浏览器进程结束。

哪些操作会造成内存泄露

  1. 意外的全局变量引起的内存泄露
  2. 闭包引起的内存泄露
  3. 没有清理的DOM元素引用
  4. 被遗忘的定时器或者回调
  5. 子元素存在引起的内存泄露
  6. IE7/8引用计数使用循环引用产生的问题

怎样避免内存泄露

  1. 减少不必要的全局变量,或者生命周期较长的对象,及时对无用的数据进行垃圾回收;
  2. 注意程序逻辑,避免死循环之类的;
  3. 避免创建过多的对象,原则:不用了的东西要及时归还

组件中的data为什么是一个函数?

如果data是对象的话,由于对象是引用类型,组件被复用的话,就会创建多个实例。本质上,这些实例用的都是同一个构造函数。这样就会影响到所有的实例,所以为了保证组件不同的实例之间data不冲突,data必须是一个函数。

为什么data函数⾥⾯要return⼀个对象
export default{
    data(){
        return {//返回一个唯一的对象,不要和其他组件共用一个对象进行返回
            menu:MENU.data,
            poi:POILIST.data
        }
    }
}
因为一个组件是可以共享的,但他们的data是私有的,所以每个组件都要return一个新的data对象,返回一个唯一的data对象,不要和其它组件共用一个对象。

因为一个组件是可以共享的,但他们的data是私有的,所以每个组件都要return一个新的data对象,返回一个唯一的对象,不要和其它组件共用一个对象。

重绘(Repaint)和回流(Reflow)

重绘和回流是渲染步骤中的一小节,但是这两个步骤对于性能影响很大。

  • 重绘是当节点需要更改外观而不会影响布局的,比如改变 color就叫称为重绘

  • 回流是布局或者几何属性需要改变就称为回流,回流也称为重排。

回流必定会发生重绘,重绘不一定会引发回流。回流所需的成本比重绘高的多,改变深层次的节点很可能导致父节点的一系列回流。

所以以下几个动作可能会导致性能问题:

  • 改变 window 大小

  • 改变字体

  • 添加或删除样式

  • 文字改变

  • 定位或者浮动

  • 盒模型

很多人不知道的是,重绘和回流其实和 Event loop 有关。

  1. 当 Event loop 执行完 Microtasks 后,会判断 document 是否需要更新。因为浏览器是 60Hz 的刷新率,每 16ms 才会更新一次。

  2. 然后判断是否有 resize或者 scroll,有的话会去触发事件,所以 resize和 scroll事件也是至少 16ms 才会触发一次,并且自带节流功能。

  3. 判断是否触发了 media query

  4. 更新动画并且发送事件

  5. 判断是否有全屏操作事件

  6. 执行 requestAnimationFrame回调

  7. 执行 IntersectionObserver回调,该方法用于判断元素是否可见,可以用于懒加载上,但是兼容性不好

  8. 更新界面

  9. 以上就是一帧中可能会做的事情。如果在一帧中有空闲时间,就会去执行 requestIdleCallback回调。

减少重绘和回流

  • 使用 translate 替代 top

  • 使用 visibility替换 display: none,因为前者只会引起重绘,后者会引发回流(改变了布局)

    把 DOM 离线后修改,比如:先把 DOM 给 display:none(有一次 Reflow),然后你修改100次,然后再把它显示出来

    不要把 DOM 结点的属性值放在一个循环里当成循环里的变量

  • 不要使用 table 布局,可能很小的一个小改动会造成整个 table 的重新布局

  • 动画实现的速度的选择,动画速度越快,回流次数越多,也可以选择使用 requestAnimationFrame

  • CSS 选择符从右往左匹配查找,避免 DOM 深度过深

  • 将频繁运行的动画变为图层,图层能够阻止该节点回流影响别的元素。比如对于 video标签,浏览器会自动将该节点变为图层。

vue中如何监控某个属性值的变化

比如现在需要监控data中, obj.a 的变化

watch: {
'obj.a': {
      handler (newName, oldName) {
        console.log('obj.a changed')
      }
   }
  }

普通watch无法监听到对象内部属性变化,只有data中数据改变时才能监听变化。因此可添加deep属性:深层遍历

computed: {
    a1 () {      
        return this.obj.a
    }
}

利用计算属性的特性来实现,当依赖改变时,便会重新计算一个新值。

同步和异步的理解

同步即sync,形象的说就是代码一行行执行,前面的代码和请求没有执行完,后面的代码和请求就不会被执行。

  • 缺点:容易导致代码阻塞
  • 优点:程序员容易理解(因为代码从上往下一行行执行,强调顺序)

异步:即async,形象地说就是代码可以在当前程序没有执行完,也可以执行后面的代码。

  • 缺点:程序员不易理解(因为不是按顺序执行的)
  • 优点:可以解决代码阻塞问题,提升代码执行效率和性能         

异步解决方案主要有三个

  • 回调函数
  • promise(重点掌握)
  • generator(了解)
  • async和await(重点掌握)

BOM和DOM对象

BOM(Browser Object Model)是指浏览器对象模型,可以对浏览器窗口进行访问和操作。使用 BOM,开发者可以移动窗口、改变状态栏中的文本以及执行其他与页面内容不直接相关的动作。 使 JavaScript 有能力与浏览器"对话"。 DOM (Document Object Model)是指文档对象模型,通过它,可以访问HTML文档的所有元素。 DOM W3C(万维网联盟)的标准。DOM 定义了访问 HTML XML 文档的标准: "W3C 文档对象模型(DOM)是中立于平台和语言的接口,它允许程序和脚本动态地访问和更新文档的内容、结构和样式。" W3C DOM 标准被分为 3 个不同的部分:

  • 核心 DOM - 针对任何结构化文档的标准模型
  • XML DOM - 针对 XML 文档的标准模型
  • HTML DOM - 针对 HTML 文档的标准模型

什么是 XML DOMXML DOM 定义了所有 XML 元素的对象和属性,以及访问它们的方法。 什么是 HTML DOM? HTML DOM 定义了所有 HTML 元素的对象和属性,以及访问它们的方法。

说说你对spa单页面应用的理解

  • SPA(single-page application)仅在web页面初始化时加载相应的HTML,JavaScipt和CSS.一旦页面加载完成,SPA不会因为用户的操作而进行页面的重新加载或跳转,取而代之的是利用路由机制实现HTML内容的变化,UI与用户的交互,避免与页面的重新加载。

  • 优点

    • 用户的体验好,快,内容的改变不需要重新加载整个页面,避免了不必要的跳转和重新渲染

    • 基于上面一点,SPA相对对服务器压力小

    • 前后端职责分离,架构清晰,前端进行交互逻辑,后端负责数据处理

  • 缺点:

    • 初次加载时耗时多:为实现单页web应用功能及显示效果。需要在加载页面的时候将javaScript,css统一加载,部分页面按需加载

    • 前进后退路由管理:由于单页应用在一个页面中显示所有的内容,所以不能使用浏览器的前进后退功能,所有的页面切换需要自己建立堆栈管理

    • seo难度较大:由于所有的内容都在一个页面中动态替换显示,所以在seo上其有着天然的弱势

this指向,new关键字

this对象是是执行上下文中的一个属性,它指向最后一次调用这个方法的对象,在全局函数中,this等于window,而当函数被作为某个对象调用时,this等于那个对象。 在实际开发中,this 的指向可以通过四种调用模式来判断。

  1. 函数调用,当一个函数不是一个对象的属性时,直接作为函数来调用时,this指向全局对象。
  2. 方法调用,如果一个函数作为一个对象的方法来调用时,this指向这个对象。
  3. 构造函数调用,this指向这个用new新创建的对象。
  4. 第四种是 apply 、 call 和 bind 调用模式,这三个方法都可以显示的指定调用函数的 this 指向。apply接收参数的是数组,call接受参数列表,`` bind方法通过传入一个对象,返回一个 this 绑定了传入对象的新函数。这个函数的 this指向除了使用new `时会被改变,其他情况下都不会改变。

new

  1. 首先创建了一个新的空对象
  2. 设置原型,将对象的原型设置为函数的prototype对象。
  3. 让函数的this指向这个对象,执行构造函数的代码(为这个新对象添加属性)
  4. 判断函数的返回值类型,如果是值类型,返回创建的对象。如果是引用类型,就返回这个引用类型的对象。

GET和POST的区别

        1.get方法通过url请求来传递用户的数据,将表单内容各字段名称与其内容,以成对的字符串连接,置于action属性所指程序的url后,数据都会直接显示在url上,就像用户点击一个链接一样,post方法通过HTTP post机制,将表单内各字段名称与其内容放置在HTML表头(header)内一起传送给服务器端交由action属性能所指的程序处理,该程序会通过标准输入(stdin)方式,见表单的数据读出并加以处理。

        2.get方式需要使用request,QueryString来取得变量的值;而post方式通过RequestForm来访问提交的内容;

        3.get方式传输的数据量非常小,一般限制在2kb左右,但是执行效率却比post方法好,而post方式传输的数据量相对较大,它是等待服务器来读取数据,不过也有字节限制,这是为了避免对服务器用大量数据进行恶意攻击。建议:除非你肯定你提交的数据可以一次性提交,否则请尽量用post方法;

        4.get方式提交数据,会带来安全问题,比如一个登录页面,通过get方式提交数据时,用户名和密码将出现在url上,如果页面可以被缓存或者其他人可以访问客户这台机器,就可以从历史记录获得该用户的账号和密码,所以表单提交建议使用post方法;

        5.get是从服务器上获取数据,post是向服务器传送数据。

        6.get方式的安全性较post方式要差些,包含机密信息的化,建议用post数据提交方式;

注意:在做数据查询时,建议用get方式,而在做数据添加、修改或删除时,建议用post方式。

作用域,作用域链

        1.js作用域也就是js识别变量的范围,作用域链也就是js查找变量的顺序

        2.先说作用域,js作用于主要包含全局作用域、局部作用域和es6的块级作用域

                全局作用域:也就是定义在window下的变量范围,在任何地方都可以访问

                局部作用域:是指在函数内部定义的变量范围

                块级作用域:简单来说用let和const在任意的代码块中定义的变量都认为是块级作用域中的变量,例如在for循环中用let定义的变量,在if语句中使用let定义的变量等。

                注意:尽量不要使用全局变量,因为容易导致全局的污染,命名冲突,对bug查找不利。

          3.所谓的作用域链就是由最内部的作用域往最外部查找变量的过程,形成的链条就是作用域链。                                      

var、let、const的区别

var、let、const三者区别可以围绕下面五点展开:

变量提升

暂时性死区

块级作用域

重复声明

修改声明的变量

使用

变量提升

var声明的变量存在变量提升,即变量可以在声明之前调用,值为undefined;

let和const不存在变量提升,即它们所声明的变量一定要在声明后使用,否则报错。

暂时性死区

var不存在暂时性死区;

let和const存在暂时性死区,只有等到声明变量的那一行代码出现,才能获取和使用该变量。

块级作用域

var不存在块级作用域;

let和const存在块级作用域

重复声明

var 允许重复声明变量

let和const在同一作用域下不允许重复声明变量

修改声明的变量

var和let可以修改;

const声明一个只读的常量。一旦声明,常量的值就不能改变。

使用

能用const的情况尽量使用const,其他情况下大多数使用let,避免使用var.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值