let 与 var

var

var声明的变量拥有全局作用域或者局部作用域

在全局中声明变量即为全局变量

在函数中声明变量即为局部变量

而var在使用过程中也逐渐暴露出许多问题

var的几大问题

变量提升

使用var来声明变量会出现变量提升的问题,即在声明变量之前就调用变量

console.log(info);//undefined

var info = 10;

出现上面情况其实是非常不好的,因为在声明之前使用的话应该去报出一个错误而不是用一个undefined给这个变量赋值。

这个问题在函数中尤为明显

var info = 10;

function fn1(){
console.log(info);//undefined
var info = 20;
} fn1();

在循环中的问题

var在循环中的问题也是相当严重

下面我遇到的一个情况

//html中有四个span
var oSpan = document.getElementsByTagName('span');
for(var i = 0 ; i < oSpan.length ; i++ ){
oSpan[i].onclick = function(){
console.log(this);//点击出现 你点的那个span
}
}

我们发现在这时是可以获得点击的元素的

但是我们把this换成oSpan[i]时就会出问题

for(var i = 0 ; i < oSpan.length ; i++ ){
oSpan[i].onclick = function(){
console.log(oSpan[i]);//点击出现 undefined
console.log(i);//点什么都是4
}
}

我们这个时候会发现我们已经选取不到事件处理函数中i的瞬时值了。而这又是因为什么呢

我们可以把代码拆开

//拆开for
var i = 0;
oSpan[i].onclick = function(){
console.log(i);
}
var i = 1;
oSpan[i].onclick = function(){
console.log(i);
}
...
var i = 3;
oSpan[i].onclick = function(){
console.log(i);
}
var i = 4; //在你点击的时候是在页面加载完才调用的函数

上面的会看出来由于var声明的变量是全局变量,所以函数中的变量接收是4

解决办法是在循环中写一个闭包函数,模拟一个块级作用域

for(var i = 0 ; i < 4 ; i++){
oSpan[i].onclick = function(arg){
return function(){
console.log(arg);//出现 0,1,2,3
}
}(i);
}

然而es6给我们提供了更好的声明变量的方式

let

在es6中,let声明的变量是块级作用域

块级作用域是指在{}中间可以有效使用

for(let i = 0; i < 4 ; i++){
oSpan[i].onclick = function(){
console.log(i);
}
}

上面的就可以找到i的瞬时值原因是每个i与下面的都是同一块作用域,而与另几个循环中的函数互不影响。所以每个函数调用的都是与其同一块作用域的i值。

let其他作用

在let声明的变量不可重复声明否者会报错

let b = 10;

let b = 20;//报错

let不会有变量提升这个问题,let会产生暂时性死区

console.log(a);//报错

let a = 20;

顶层对象的属性

在浏览器的顶层对象是window,在Node环境中是global

在es5中顶层的属性与全局变量是等价

window.a = 1;
a = 2;
console.log(window.a)//2

由于顶层对象的属性与全局变量相关,就会产生许多问题

  1. 无法再编译时就提示变量未声明的错误,只有运行在会知道

  2. 容易不知不觉的就创建出全局变量,导致顶层对象的属性到处都可以读写,这非常不利于模块化编程

  3. window对象有实体含义,指的是浏览器窗口对象,这样也是不合适的

但是let声明的变量不属于顶层对象的属性

var a = 1;

console.log(this.a);//1

let b = 1;

console.log(this.b);//undefined

const

const也是es6的声明方式之一

const声明的变量大多数是做为一个常量,而作为常量时不可对值进行修改,变成只读模式


const INFO = 10; INFO = 20; //报错 const INFO = 20;//报错

而当const声明的是一个引用数据类型的时候,引用类型内的值是可以修改的,因为引用类型的值存放在堆中的。修改操作是在堆中进行,而变量储存的是地址,不会被修改,而地址指向的数据已经发生改变,故而const声明的变量的值被修改了

const arr = [1,2,3,4];

arr.push(5);

console.log(arr);//[1,2,3,4,5]

es6 新增变量声明方式的更多相关文章

  1. ES6 - 基础学习(2): 新的变量声明方式 let 与 const

    ES6)新增加了两个重要的 JavaScript 关键字:let 和 const.以前声明变量时只有一种方式:var,ES6对声明方式进行了扩展,现在可以有三种声明方式了. 1.var:variabl ...

  2. 哟,来看看JS里面变量声明方式

    点点点点点点进来.点击此处领取双十一梦想大礼包. 终于被我忽悠进来了?老弟,不骚一下你不往里面点是吧,还想大礼包?想着吧. 今天要说的如题,JS里面变量声明方式.可能一提到这个话题大家能很快的打出来, ...

  3. javascript中var let const三种变量声明方式

    javascript中var let const三种变量声明方式 1.var  ①var表示声明了一个变量,并且可以同时初始化该变量. ②使用var语句声明的变量的作用域是当前执行位置的上下文:一个函 ...

  4. es6系列-变量声明

    es6系列所有文章都是阅读阮一峰老师的<ES6标准入门>(第2版)所做的读书笔记.方便日后查阅相关基础知识. git地址: https://github.com/rainnaZR/es6- ...

  5. 二.ES6新的声明方式

    前言: 以前我们在声明时只有一种方法,就是使用var来进行声明,ES6对声明的进行了扩展,现在可以有三种声明方式了. 字面理解ES6的三种声明方式: var:它是variable的简写,可以理解成变量 ...

  6. JS变量声明方式

    在JavaScript中有三种声明变量的方式:const  var let const:用于声明常量.注意:定义的变量的时候,必须同时初始化,且其值之后不可以修改. var:最常用的声明变量关键字.  ...

  7. ES6新增变量

    声明let let 声明的变量不存在预解析 console.log(flag) var flag = 123 //123 let flag = 456 //undefined let声明的变量不允许重 ...

  8. 怎样理解"不推荐不使用var的变量声明方式"这句话

    答: 因为不使用var声明的变量不会被预解析, 如下: console.log(a); console.log(b); var a = 1; b = 2;

  9. es6变量声明和解构赋值

    /*声明: * 本文内容多为学习借鉴性内容,大部分非原创 * 特别感谢阮一峰的 ECMAScript6 入门,推荐大家学习 */ 一.es5变量声明的不足 1.变量提升和函数声明提升 es5的代码加载 ...

随机推荐

  1. 原创:mysql5 还原至mysql 8.0.11数据库链接配置提示错误(修改内容有三处

    原创:mysql5 还原至mysql 8.0.11数据库链接配置提示错误改有三: a) mysql 连接jar包版修改 b)类路径修改 c)配置连接池地址修改 因版本升级,首先要修改 1:mysql- ...

  2. 阿里妈妈的iconfont的引用问题

    一.先进官网 我们看到了上面的这些图标,是不是很心动,阿里妈妈就是给力,给马老师点赞,但是问题来了我们怎么去使用呢. 二.点击图标 嘿嘿,上面的操作步骤我就不多说了吧,我相信大家都会做的,接下来我们就 ...

  3. SQL中的事务ACID

    概述: 事务是由一系列语句构成的逻辑工作单元.事务和存储过程等批处理有一定程度上的相似之处, 通常都是为了完成一定业务逻辑而将一条或者多条语句“封装”起来,使它们与其他语句之间出现一个逻辑上的边界,并 ...

  4. clr via c# 程序集

    1,程序集的种类 强命名程序集 使用了公钥进行签名 可以应用CLR的安全策略.---可以全局部署---可以部署到一些公认位置. 弱命名程序集 只能私有部署----部署到应用程序基目录或其子目录中 2, ...

  5. 建造者模式(Builder)——从组装电脑开始

    建造者模式(Builder)--从组装电脑开始 建造者模式概括起来就是将不同独立的组件按照一定的条件组合起来构成一个相对业务完整的对象.调用者无需知道构造的过程. 我们从组装电脑开始 让我们从买组装电 ...

  6. qt creator源码全方面分析(2-4)

    目录 Qt Creator API Reference 库 核心库 其他库 插件 Qt Creator API Reference Qt Creator的核心基本上只是一个插件加载器.所有功能都在插件 ...

  7. opencv —— boxFilter、blur、GaussianBlur、medianBlur、bilateralFilter 线性滤波(方框滤波、均值滤波、高斯滤波)与非线性滤波(中值滤波、双边滤波)

    图像滤波,指在尽量保留图像细节特征的条件下对目标图像的噪声进行抑制,是图像与处理中不可缺少的操作. 邻域算子,指利用给定像素及其周围的像素值,决定此像素的最终输出值的一种算子.线性邻域滤波器就是一种常 ...

  8. opencv —— copyTo 设置与操作感兴趣区域(ROI)

    感兴趣区域:ROI 对感兴趣区域进行的一系列操作,相当于直接在原图相应部分进行操作. Mat imageROI = srcImage(Rect(0,0,dstImage.cols, dstImage. ...

  9. AE神奇插件TypeMonkey—抖音点赞100W+的文字视频特效是如何做出来的?

    现在最火的东西,短视频必须要拥有姓名啦,抖音这些短视频平台风头正盛,我们也常常在上面看到一些文字动画Vlog,看着并不复杂,但是有些却有上百万的点击量,今天介绍的一款神奇插件——TypeMonkey, ...

  10. 【感知机模型】手写代码训练 / 使用sklearn的Perceptron模块训练

    读取原始数据 import pandas as pd import numpy as np in_data = pd.read_table('./origin-data/perceptron_15.d ...