原文来自:http://www.cnblogs.com/Marydon20170307/p/7505964.html
js声明变量的三种方式
声明:本篇文章的创作灵感来源于博主-奔跑的铃铛关于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 局部变量
声明在函数体内,只有在函数体内可访问到该变量。
4.声明变量的3种方式及作用域
UpdateTime--2017年9月13日15:06:03
4.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再次声明一次并改变其值,函数外面的该变量的值不会发生改变。
4.2 使用const
const用于修饰常量,定义的变量不可修改,而且必须初始化,声明位置不限(通常声明在js开头),与java类的final关键字性质一样
举例:
<script type="text/javascript"> function test() { const testConstant = "测试常量"; alert(testConstant); testConstant = "改变常量值";// 直接报错 } test(); </script>
4.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 " + i + " 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.4 声明变量的要项
4.4.1 js声明的变量取值的原则:就近原则;
4.4.2 js是弱类型语言,不同的数据类型可以用同一个变量名表示;
4.4.3 函数内部声明的变量,不会影响函数外部同名的变量的值。
举例:
var testVarValue = "测试就近原则"; <script type="text/javascript"> function test() { const testRepeatStatement = "测试用一个变量赋予不同的类型及不同的值"; alert(testRepeatStatement);// 测试用一个变量赋予不同的类型及不同的值 } test(); </script>
5.如何避免全局污染?
方法:闭包
举例:
(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
闭包的优缺点说明:
优点:设计私有的方法和变量,保护函数内的变量安全;
弊端:闭包有一个非常严重的问题,那就是内存浪费问题,这个内存浪费不仅仅因为它常驻内存,更重要的是,对闭包的使用不当会造成无效内存的产生。