JS中let 和 var 的区别和分割

前言:置信很多人和我一样,应用js也有一段时间了,然而仍然将不明确在js中 var申明的变量和let 申明的变量到底有什么区别。本文就给各位介绍分明。

一,弄清楚共同点

要想理分明2者之间的区别,先搞明确它们之间的共同点

  1. JS 中的变量是弱类型能够保留所有类型的数据,即变量没有类型而值有类型。let 和 var 与变量类型无关。
  2. var/let/const共同点是全局作用域中定义的变量,能够在函数中应用
var name = 'xiaoming';function show() {    return name;}console.log(show());
  1. 函数中申明的变量,只能在函数及其子函数中应用
function abc() {  var name = "xiaoming";  function def() {    console.log(name);  }  def(); //子函数后果: xiaoming  console.log(name); //函数后果: xiaoming}abc();console.log(name); //全局拜访: name is not defined

函数外部定义的变量,在内部无奈失常拜访

var name = "lulu";function hd() {  var name= "goudan";  console.log(name); //goudan}hd();console.log(name); //lulu

当初来通过例子感触区别

先运行以下2局部代码:
代码1:

console.log(a); //undefinedvar a = 1;console.log(a);  //1

代码2:

console.log(a); let a = 1;console.log(a);

能够发现,代码1运行不会报错,在没有申明 var a之前就应用变量a,输入undefined,然而代码2运行会间接报错’Cannot access 'a' before initialization‘ ; 这个就是var 和let之间的区别所造成的,为什么呢?
这里牵扯到“变量晋升”,解析器会先解析代码,而后把申明的变量的申明晋升到最前,这就叫做变量晋升
代码1其实会被解析器解析为:

var a;console.log(a); //undefineda = 1;console.log(a);  //1

应用 var 定义的代码,申明会被晋升到后面,赋值还在原地位

坚固一下常识,上面代码你认为输入的后果是什么?

var name = "Trump";function Chairman() {  if (false) {    var name = "Biden";  }  console.log(name);}Chairman();

咱们剖析一下,首先定义全局变量name是Trump, 函数中的赋值语句var name = "Biden";没有执行,那么name的值还是全局变量的Trump!不好意思,最终的后果是undefined。
函数外部的确是能够拜访到全局定义的变量,然而当你在函数外部定义变量和全局变量并不抵触!你会想var name = "Biden";压根没有执行啊?而且就算不输入Biden也会输入Trump啊,怎么会输入undefined?这就是var变量给咱们带来的麻烦;代码被解析器主动晋升了!以上代码会被解析器解析为:

var name = "Trump";function Chairman() {var name;  if (false) {   name = "Biden";  }  console.log(name);}Chairman();

这样一来,即便没有走到赋值语句处,在函数外部仍然开拓了新的内存地址来保留局部变量name,所以最终输入的是undefined。
这其实算是js语言晚期倒退的一个bug。在es6的时候js推出了"暂时性死区 "这个概念,也就是TDZ;它存在的目标就是规定变量必须申明先申明后应用;让程序更稳固。具体来说,当程序执行到蕴含 let 或 const 申明的代码块时,会创立一个称为暂时性死区的区域,该区域从申明开始直到块完结。在这个区域内,变量尽管曾经被申明,然而在申明之前拜访该变量会导致引擎抛出一个谬误。
这个个性能够让咱们的代码更加的强壮,说到减少js代码的健壮性,我举荐大家在编码过程中应用js的“严格模式”:
严格模式能够让咱们及早发现错误,使代码更平安标准,支流框架都采纳严格模式,严格模式也是将来 JS 规范
变量必须应用关键词申明,未声明的变量不容许赋值

'use strict'age = 100;console.log(age);

关键词不容许做变量应用

"use strict";var public = 'houdunren.com';

变量参数不容许反复定义

"use strict";function abc(name,name){  console.log(name);}

独自为函数设置严格模式

function strict(){  "use strict";  return "严格模式";}function notStrict() {  return "失常模式";}

那么上面介绍除了let有TDZ爱护这个长处外的其它与var的不同之处

  1. let存在块作用域个性,变量只在块域中无效
{    let name= 'lulu',age= 18;    console.log(name); //lulu}console.log(name); //name is not defined

能够看到将代码放在大括号中 ,那么这个变量只在块内失效
然而块外部能够拜访到下层作用域的变量

let age =19;{    let name= 'lulu';    console.log(age); //19}console.log(age); //19
  1. let 定义的全局变量不会被保留在window对象中

在JavaScript中,一个浏览器窗口就是一个window对象。会保留一些和窗口无关的信息
比方分辨率其实就是在window中保留,如果是var申明的全局变量,也被保留在window中

console.log('显示屏宽度'+screen.width);console.log('显示屏宽度'+window.screen.width);//值雷同var name = "lulu";console.log('name'+name);console.log('name'+window.name);//值雷同

var这个个性其实也没什么卵用,反而会造成歧义


总结

let和var的区别:

  1. ES6引入let 和 const ,减少''TDZ"个性,规定必须先申明后应用。
  2. let存在块作用域个性,变量只在块域中无效。
  3. let全局变量与window中的变量分来到。

我集体在捋分明let 和 var的区别和分割之后。当前决定当前放弃应用var!,因为let齐全能够取代它,而且还要做的更好。