一、参考链接

  本篇文章的创作灵感来源于博主-奔跑的铃铛关于js中const,var,let区别的介绍,特此鸣谢!!!

二、基础知识

UpdateTime--2017年9月12日15:18:28

1.使用变量的步骤:a.声明-->b.赋值-->3.调用

正确用法:

<script type="text/javascript">
// 方式一:声明和赋值不分离
var correctUsage = "正确使用变量的方式一";
alert(correctUsage);// 能够弹出来该变量所对应的值
// 方式二:声明和赋值分离
var correctUsage2;
correctUsage2 = "正确使用变量的方式二";
alert(correctUsage2);// 能够弹出来该变量所对应的值
</script>

错误用法:

<script type="text/javascript">
var correctUsage;
// 错误一:没有赋值就使用
alert(correctUsage);// undefined
// 错误二:没有赋值就拼接字符串
correctUsage+="没有赋值就改值";
alert(correctUsage);// undefined没有赋值就改值
</script> 

2.变量的产生与死亡

  以使用var关键字声明变量为例,
  2.1 声明在函数外部的变量
  产生:js加载到该变量所在行时产生;
  死亡:js代码加载完毕,变量死亡。
  2.2 声明在函数内部的变量
  前提:该变量所在的函数被调用
  产生:js执行到该变量所在行时产生;
  死亡:该变量所在的函数执行结束。
  举例:

  情景一:函数只声明,不调用

<script type="text/javascript">
function test() {
var aa = "test";
aa += "只声明,但不调用该函数时,该函数会不会执行?";// 添加内容
alert(aa);
aa = "该函数的变量不会执行!"; // 重新赋值
alert(aa);
}
</script>

  说明:上面2个alert不会执行
  情景二:声明并调用该函数

<script type="text/javascript">
// 1.声明该函数
function test() {
var aa = "test";
aa += "只声明,但不调用该函数时,该函数会不会执行?";// 添加内容
alert(aa);
aa = "该函数的变量不会执行!"; // 重新赋值
alert(aa);
}
// 2.调用该函数
test();
</script>

  说明:上面2个alert均会执行

3.全局变量与局部变量

  3.1 全局变量

  声明在函数体外,任何地方都可访问到该变量。

  3.2 局部变量

  声明在函数体内,只有在函数体内可访问到该变量。

三、声明变量的3种方式及作用域

  UpdateTime--2017年9月13日15:06:03

  1 使用var(最常见)

  var声明的变量可以是全局的(函数外面),也可以是函数级的(函数内部)

function test() {
globalVar = "这是一个全局变量";
var partialVar = "这是一个局部变量";
}
test();
alert(globalVar);// 这是一个全局变量
alert(partialVar);// 直接报错 

  说明:函数内部声明变量的时候,一定要使用var命令。如果不用的话,你实际上声明了一个全局变量!

  情景一:

var varLocation = "函数外部声明并赋值";
function test() {
varLocation = "函数内部改值";
alert(varLocation);// 函数内部改值
}
test();
alert(varLocation);// 函数内部改值

  说明:函数外面声明的变量,在函数内部改变该变量的值后,函数外面的该变量的值也随之改变。   

  情景二:

var varLocation = "函数外部声明并赋值";
function test() {
var varLocation = "函数内部改值";
alert(varLocation);// 函数内部改值
}
test();
alert(varLocation);// 函数外部声明并赋值  

  说明:在函数外面使用var声明一个变量后,再在函数内部使用var再次声明一次并改变其值,函数外面的该变量的值不会发生改变。

  2 使用const

  const用于修饰常量,定义的变量不可修改,而且必须初始化,声明位置不限(通常声明在js开头),与java类的final关键字性质一样

  举例:

<script type="text/javascript">
function test() {
const testConstant = "测试常量";
alert(testConstant);
testConstant = "改变常量值";// 直接报错
}
test();
</script>   

  3 使用let

  let声明的变量在{}中使用,变量的作用域限制在块级域中

  举例:使用js动态给ul添加li对象并点击第几项,显示当前点击是第几个

window.onload = function() {
var ul = document.getElementById("ulList");
//
for (var i = 1; i <= 5; i++) {
// 创建一个li对象
var li = document.createElement("li");
// li标签内内容设置为:Itemi
li.appendChild(document.createTextNode("Item " + i));
// 声明一个块级变量j,并将i赋给j
let j = i;
// 绑定点击事件
li.onclick = function() {
alert("Item " + j + " is clicked.");
};
// 将li对象item拼接到ul标签体内
ul.appendChild(li);
}
}

   错误方式:

window.onload = function() {
var ul = document.getElementById("ulList");
//
for (var i = 1; i <= 5; i++) {
// 创建一个li对象
var li = document.createElement("li");
// li标签内内容设置为:Itemi
li.appendChild(document.createTextNode("Item " + i));
// 绑定点击事件
li.onclick = function() {
alert("Item " + i + " is clicked.");
};
// 将li对象item拼接到ul标签体内
ul.appendChild(li);
}
}

  结果:点击每个li,提示的都是“Item 6 is clicked.”

  扩展:使用var如何实现这种效果?闭包

window.onload = function() {
var ul = document.getElementById("ulList");
//
for (var i = 1; i <= 5; i++) {
// 创建一个li对象
var li = document.createElement("li");
// li标签内内容设置为:Itemi
li.appendChild(document.createTextNode("Item " + i));
// 绑定点击事件
li.onclick = (function(i) {
return function () {
alert("Item " + i + " is clicked.");
};
})(i);// 闭包
// 将li对象item拼接到ul标签体内
ul.appendChild(li);
}
}

  说明:采用的闭包的方式在绑定的时候已经把j的值已经传递给对应的click事件了,所以能够实现相同的结果,但是,从程序的可维护性来说不推荐使用。

  4 声明变量的要项  

  js声明的变量取值的原则:就近原则;

  js是弱类型语言,不同的数据类型可以用同一个变量名表示;

  函数内部声明的变量,不会影响函数外部同名的变量的值。

四、如何避免全局污染? 

  方法:闭包

  举例一:

(function() {
// 声明一个JSON对象
var JsonObj = {};
// 定义该对象的属性及属性值
JsonObj.name = "对象的属性";
// 定义该对象的方法
JsonObj.method = function() {
alert("测试是否能够调用该方法");
return JsonObj.name;
}
// 通过操作window对象,供外部访问该对象的属性和方法
window.GlobalObj = JsonObj;
})();
// 调取该对象的方法并接受返回值
var name = GlobalObj.method();//获取的是返回值name
alert(name);// 对象的属性
// 只获取该方法但不调用
var method = GlobalObj.method;//获取的是对象GlobalObj2的method1()方法
alert(method);
// function() {
// alert("测试是否能够调用该方法");
// return JsonObj.name;
// }
// 调用接受到的方法,但不接收返回值
method(); 

  UpdateTime--2017年11月8日08:27:48

  闭包的优缺点说明:

  优点:设计私有的方法和变量,保护函数内的变量安全;

  弊端:闭包有一个非常严重的问题,那就是内存浪费问题,这个内存浪费不仅仅因为它常驻内存,更重要的是,对闭包的使用不当会造成无效内存的产生。

2020/04/16

  关于let变量的实际运用

  如上图所示,想实现的效果就是:鼠标离开文本框的时候,自动将一级指标所对应的二级指标打分结果进行求和,并将计算结果自动填充到合计栏。

  笨方法实现:

$(function(){
// 合计
$(".index_01").on('blur', function(){
var sum = 0;
$(".index_01").each(function(){
// sum += parseInt($(this).val());// 使用parseInt,字符串转数字失败
sum += new Number($(this).val());
});
$("#score_01").text(sum);
});
$(".index_02").on('blur', function(){
var sum = 0;
$(".index_02").each(function(){
sum += new Number($(this).val());
});
$("#score_02").text(sum);
});
$(".index_03").on('blur', function(){
var sum = 0;
$(".index_03").each(function(){
sum += new Number($(this).val());
});
$("#score_03").text(sum);
});
$(".index_04").on('blur', function(){
var sum = 0;
$(".index_04").each(function(){
sum += new Number($(this).val());
});
$("#score_04").text(sum);
});
$(".index_05").on('blur', function(){
var sum = 0;
$(".index_05").each(function(){
sum += new Number($(this).val());
});
$("#score_05").text(sum);
});
});

  借助for循环实现

function indexTotalCalculate(firsIndexCount) {
  if (firsIndexCount >= 10) return;
  // 有多少个一级指标就执行多少次
  for (var i = 1; i <= firsIndexCount; i++) {
    // 必须使用变量let
    let index = '.index_0' + i;
    let score = '#score_0' + i;
// var index = '.index_0' + i;
// var score = '#score_0' + i;
    $(index).on('blur', function(){
      var sum = 0;
      $(index).each(function(){
        sum += new Number($(this).val());
      });
      $(score).text(sum);
    });
  }
}
$(function(){
// 自动求和
  indexTotalCalculate(5);
});

  这样,避免了冗余的代码,也实现了同样的效果  

  但是,刚开始的时候,需要用let声明变量的地方使用了var,导致的结果就是:  

  只有最后一个一级指标能够进行自动求和运算,而前面的4个都没有实现。

  原因就是由于var的作用域是函数级别,所以同一个函数内不管使用for循环声明并赋值多少次,其值都是最后一次所赋的值,也就造成对最后一个指标重复了5次绑定失去焦点事件的结果。

  也就是实际解析出来的是5个一样的代码

$(".index_05").on('blur', function(){
var sum = 0;
$(".index_05").each(function(){
sum += new Number($(this).val());
});
$("#score_05").text(sum);
});
$(".index_05").on('blur', function(){
var sum = 0;
$(".index_05").each(function(){
sum += new Number($(this).val());
});
$("#score_05").text(sum);
});
$(".index_05").on('blur', function(){
var sum = 0;
$(".index_05").each(function(){
sum += new Number($(this).val());
});
$("#score_05").text(sum);
});
$(".index_05").on('blur', function(){
var sum = 0;
$(".index_05").each(function(){
sum += new Number($(this).val());
});
$("#score_05").text(sum);
});
$(".index_05").on('blur', function(){
var sum = 0;
$(".index_05").each(function(){
sum += new Number($(this).val());
});
$("#score_05").text(sum);
});

  这样的话,循环多少次也是白瞎!!!     

 

js声明变量的三种方式及作用域的更多相关文章

  1. js声明变量的三种方式

    JS 声明变量的三种方式 (1)使用变量步骤:a.声明-->b.赋值-->3.调用 正确用法: <script type="text/javascript"> ...

  2. JavaScript声明全局变量的三种方式

    JavaScript声明全局变量的三种方式   JS中声明全局变量主要分为显式声明或者隐式声明下面分别介绍. 声明方式一: 使用var(关键字)+变量名(标识符)的方式在function外部声明,即为 ...

  3. 前端js,css文件合并三种方式,bat命令

    前端js,css文件合并三种方式,bat命令 前端js文件该如何合并三个方式如下:1. 一个大文件,所有js合并成一个大文件,所有页面都引用它.2. 各个页面大文件,各自页面合并生成自己所需js的大文 ...

  4. CentOS添加环境变量的三种方式

    CentOS添加环境变量的三种方式,以添加php环境变量为例,假定php的安装目录为 /usr/local/php5 一.仅对当前会话临时生效 [root@bogon ~]# export PATH= ...

  5. js获取时间戳的三种方式

      js获取时间戳的三种方式 CreateTime--2018年5月23日08:44:10 Author:Marydon // 方式一:推荐使用 var timestamp=new Date().ge ...

  6. JS基础语法---创建对象---三种方式创建对象:调用系统的构造函数;自定义构造函数;字面量的方式

    创建对象三种方式: 调用系统的构造函数创建对象 自定义构造函数创建对象(结合第一种和需求通过工厂模式创建对象) 字面量的方式创建对象 第一种:调用系统的构造函数创建对象 //小苏举例子: //实例化对 ...

  7. js中定义变量的三种方式const,val,let 的区别

    js中三种定义变量的方式const, var, let的区别. 1.const定义的变量不可以修改,而且必须初始化. 1 const b = 2;//正确 2 // const b;//错误,必须初始 ...

  8. JavaScript面向对象(三)——继承与闭包、JS实现继承的三种方式

      前  言 JRedu 在之前的两篇博客中,我们详细探讨了JavaScript OOP中的各种知识点(JS OOP基础与JS 中This指向详解 . 成员属性.静态属性.原型属性与JS原型链).今天 ...

  9. JN_0003:JS定义变量的3种方式

    js中三种定义变量的方式const, var, let的区别. 1,const定义的变量不可以修改,而且必须初始化. 2,var定义的变量可以修改,如果不初始化会输出undefined,不会报错. 3 ...

随机推荐

  1. 【动态规划】【记忆化搜索】hdu5965 扫雷

    f(i,j,k)表示第i行,放的雷的状态为j{0表示不放,1表示往上放,2表示往下放,3表示上下都放},剩余还有k(0<=k<=2)个要放的方案数. 先给出我这个sb写的错误代码,死都没调 ...

  2. 【搜索】【剪枝】bzoj1306 [CQOI2009]match循环赛

    dfs+剪枝*4(通过得很勉强): 1.只枚举一半的比赛,另一半直接得出. 2.处理前缀和,若大于目标得分则剪枝 3.前缀和加上若接下来全胜的得分 仍小于 目标得分,则剪枝. 4.枚举到每个人的最后一 ...

  3. 用flask开发个人博客(26)—— 利用config.py配置文件动态的创建不同的Flask对象

    原文:https://blog.csdn.net/hyman_c/article/details/52877704 对配置进行封装的目的是根据不同的使用场景,给flask的app赋予不同的config ...

  4. [NOIp2017提高组]逛公园

    题目大意: 给你一个有向图,若用dis(u,v)表示从u到v的最短路长度,求从1到n的长度不超过dis(1,n)+k的路径数. 思路: 首先分别预处理出以1,n为起点的单.源最短路. 对于合法的边重构 ...

  5. 求n以内的质数的数量

  6. 随机数选择器 Exercise07_13

    import java.util.Scanner; /** * @author 冰樱梦 *时间:2018年下半年 *题目:随机数选择器 */ public class Exercise07_13 { ...

  7. Problem D: 零起点学算法95——弓型矩阵

    #include<stdio.h> #include<string.h> int main() { ][]; while(scanf("%d%d",& ...

  8. Python学习笔记 | 关于python数据对象 hashable & unhashable 的理解

    文章目录 写在前面 hashable & unhashable mutable & immutable 实例检测 后续思考 参考文章 写在前面 Hash(哈希.散列)是一个将大体量数据 ...

  9. CDOJ 1280 772002画马尾 每周一题 div1 矩阵快速幂 中二版

    "问题:众所周知772002很喜欢马尾,所以他决定画几幅马尾送给他的女朋友. 772002会画m种马尾,772002还有n张纸,n张纸分别编号1到n,每张纸上只能画一种马尾. 然而77200 ...

  10. Xcode9出现错误safe area layout guide before ios 9 真正解决办法

    网上很多解决办法瞎扯淡,以讹传讹之势愈演愈烈. 正解是选中控制器,右边面板的Builds for 选择iOS9.0 and Later,如下图红框广为流传的错解是不勾选Use Safe Area La ...