javascript 中 var let const 的区别
变量的命名
如在javascript里,onclick 必须要写出onclick,不能写成onClick;)
如:var mood = "happy"; MOOD=“sad”; 他们是两个不同的变量进行赋值
变量不能是系统关键字和保留字 ,比如
true、if、while、class 等。 let class = 'houdunren';变量名由:字母 ,
下划线,
$
数字
第一个字母必须是 “字母,下划线,或$”
正确命名:尽量取有意义的英文名或英文缩写
i
lvye_study
_lvye
$str
n123
通常驼峰格式是函数名,方法名,和对象属性命名的首选格式 var myMood = "hapy"
变量能保存的数据类型 很多种
变量:未知数 存储一个值 这个值可以发生改变
变量是松散型的,意思是变量可以保存任何类型的数据,每个变量只不过是一个用于 保存任意值的命名占位符
如数字 字符串
//当向变量分配文本值时,应该用双引号或单引号包围这个值。
//当向变量赋的值是数值时,不要使用引号。如果您用引号包围数值,该值会被作为文本来处理。
var pi=3.14; //3.14
var person="John Doe"; //John Doe
var answer='Yes I am!';//Yes I am!
<script> // 在JS中变量类型由所引用的值决定 (弱类型) var web = "hhhh"; console.log(typeof web); //string web = 99; console.log(typeof web); //number web = {}; console.log(typeof web); //object </script>
var name=" 琪琪",
gender;
console.log(name,typeof name); //琪琪string
console.log(gender,typeof gender); //undefined "undefined
虽然关键字var不是必须的,但是最好每次声明一个新变量都加上;
需要注意的是变量本身是没有意义的,只是数据的媒介(代号),我们说的变量默认是这个变量名所代表的数据,并不是这个变量名本身;这点需要注意的;变量声明
javascript的变量都是由var 声明,
语法: var 变量名 = 值
<script>
//因为变量的值是可以改变的,所以在变量声明和赋值的时候,后面的会覆盖前面的。 输出变量,一定不要加引号
var a = 10; document.write(a); //10
var b = 20; b = b + 1; document.write(b); //21 在原来的基础上+1
var c = 10; c = 16; document.write(c); //16 后面的会覆盖前面的
var d = 10; d = d + 1; d = d - 6; document.write(d); //5
//可以同时声明多个变量
var a=6,b=9;
console.log(b);//9
//变量可以更换不同类型的数据
var n= 'hhhhhh';
console.log(typeof n);//string
f = 18;
console.log(typeof f);//number
</script>
注意变量的声明和定义是两回事;
var name; //变量声明
name="琪琪"; //变量定义
var name="琪琪"; //变量声明+定义
//分析var name="琪琪"; 分两步走
第一步 var name;先声明一个name的变量;
第二步 name="琪琪" 创建数据"琪琪"这个字符串,
并且把字符串"琪琪"这条数据赋值给name这个变量;
在定义(赋值)变量的name值;
这个时候name的类型就是所代表值的类型;
例子
创建了名为 carname 的变量,并向其赋值 "Matt",然后把它放入 id="demo" 的 HTML 段落中
<body>
<p>点击这里创建变量,并显示结果</p>
<button onclick="myFunction()">点我</button>
<p id="demo"></p>
<script>
function myFunction(){
var carmame="Matt";
document.getElementById("demo").innerHTML=carmame;
}
</script>
</body>
Value = undefined
//未使用值来声明的变量,其值实际上是 undefined。
var a;
console.log(a);//undefined
变量提升 (函数声明和变量声明总是会被解释器悄悄地被"提升"到方法体的最顶部)
变量可以先使用后声明 不会报错 会显示undefinde
function foo(){
console.log(age);
var age=26;
}
foo();//undefinde
//等价于下面这个代码
function foo(){
var age;
console.log(age);
age=26;
}
foo(); //undefined
function test(){
console.log(value);
}
test();//undefined
var value="123";
test();//123
//等价于下面这个代码
var value;
function test(){
console.log(value);
}
test();
value="123";
test();
function test(){
console.log(value);//undefined
var value="456";
console.log(value);//456
}
var value="123";
test();
//等价于下面的写法
function test(){
var value;
console.log(value);
value="456";
console.log(value);
}
var value="123";
test();
function test(condition){
if(condition){
var value="123";
console.log(value);
}else{
console.log(value);//undefined
}
}
test(false);
/* condition为false,进入了test函数的else分支,此时并没有定义value,
但是打印出来仍然是undefined,而不是报错,在预编译阶段,
javascript引擎将上面的代码修改成下面这样, */
function test(condition){
var value;
if(condition){
value="123";
console.log(value);
}else{
console.log(value);
}
}
test(false);
在循环条件中声明的变量i,在循环体外面,仍然可以访问
for(var i=0;i<5;i++){}
console.log(i);//5
反复多次使用var声明同一个变量是可以的 值会后面的覆盖前面的
function foo(){
var age = 16;
var age=15;
var age=9;
console.log(age);//9
}
foo();
ES2015(ES6) 新增加了两个重要的 JavaScript 关键字: let 和 const。
let 声明的变量只在 let 命令所在的代码块内有效。
const 声明一个只读的常量,一旦声明,常量的值就不能改变。
在 ES6 之前,JavaScript 只有两种作用域: 全局变量 与 函数内的局部变量。
在函数外声明的变量作用域是全局的: 在 JavaScript 程序的任何地方都可以访问。
<body>
<p>全局变量在任何脚本和函数内均可访问</p>
<p id="demo"></p>
<script>
var carname = "Matt";
function myFunction(){
document.getElementById("demo").innerHTML="我可以显示"+carname;
}
myFunction();
</script>
</body>
在函数内声明的变量作用域是局部的(函数内): 函数内使用 var 声明的变量只能在函数内容访问,如果不使用 var 则是全局变量
<body>
<p>局部变量在声明的函数外不可以访问</p>
<p id="demo"></p>
<script>
document.getElementById("demo").innerHTML="carname的类型是" +typeof carname;
function myFunction(){
var carname = "Matt";
}
myFunction();
</script>
</body>
let 声明
let有四大主要特性:存在块级作用域,没有变量提升,暂时性死区,不允许重复声明。 这和var的变量特性都相反的
存在块级作用域
使用 var 关键字声明的变量不具备块级作用域的特性,它在 {} 外依然能被访问到。 在 ES6 之前,是没有块级作用域的概念的。 如果要实现块级作用域 借助立即执行匿名函数来实现
使用let 关键字来实现块级作用域。
<script>
{
var a=1;
}
console.log(a);//1 可以使用变量a
//如果要实现块级作用域,通常借助立即执行匿名函数来实现:
(function(){
var a = 1;
}());
console.log(a);//出错,not defined
//let 关键字来实现块级作用域。
//let 声明的变量只在 let 命令所在的代码块 {} 内有效,在 {} 之外不能访问。
{
let a = 1;
}
console.log(a); //出错, not defined */
</script>
没有变量提升
//var 关键字定义的变量可以先使用再声明 , 因为变量提升
console.log(a); //undefined
var a =1;
//let 关键字定义的变量必须需要先声明再使用。不可以先使用再声明会 这样会报错
console.log(a); //出错, not defined
let a = 1;
暂时性死区
var a = 1; if(true){ a = 2; var a; console.log(a);//var允许重复声明,而且变量提升,故a=2正常赋值 } //在块级作用域内,若存在用let命令声明的变量,则所在区块对该变量形成封闭作用域, //也就是该变量无视外部的同名变量。而又因为不存在变量提升,所以在该区块中,不能在声明前使用该变量。 var a = 1; if(true){ a = 2; let a; console.log(a);//出错 not defined }
不允许重复声明
//var 关键字声明的变量在任何地方都可以修改 ,且后面的会覆盖前面的
var x = 2;//合法
var x = 3;//合法
console.log(x);//3
//let 不允许同一个块作用域中出现沉余声明
let x = 2; // 合法
let x = 3; // 不合法
{
let x = 4; // 合法
let x = 5; // 不合法
}
// let var 在同一个块作用域中混用也会报错
var x = 2; // 合法
let x = 3; // 不合法
{
var x = 4; // 合法
let x = 5 // 不合法
}
let x = 2; // 合法
var x = 3; // 不合法
{
let x = 4; // 合法
var x = 5; // 不合法
}
//let 关键字在不同作用域,或不同块级作用域中是可以重新声明赋值的:
let x = 2; // 合法
{
let x = 3; // 合法
}
{
let x = 4; // 合法
}
//也就是嵌套使用相同的标识符不会报错 ,因为同一个块中没有重复声明
var name="LiLi";
console.log(name);//LiLi
if(true){
var name="Mi";
console.log(name);//Mi
}
let age=30;
console.log(age);//30
if(true){
let age=26;
console.log(age);//26
}
循环作用域
<body>
<p id="demo"></p>
<script>
//使用 var 关键字,它声明的变量是全局的,包括循环体内与循环体外。
var i=5;
for(var i=0;i<10;i++){
//一些代码
}
document.getElementById("demo").innerHTML=i; //10
//使用 let 关键字, 它声明的变量作用域只在循环体内,循环体外的变量不受影响。
let i=5;
for(let i=0;i<10;i++){
//一些代码
}
document.getElementById("demo").innerHTML=i;//5
</script>
</body>
//for循环的计数器,就很合适使用let。
var a = [];
for (var i = 0; i < 10; i++) {
a[i] = function() {
console.log(i);
}
}
a[6](); // 10
//变量i是var声明的,在全局范围内有效,所以每次循环新的i值都会覆盖旧值,导致最后输出的是最后一轮的i的值。
var a = [];
for (let i = 0; i < 10; i++) {
a[i] = function() {
console.log(i);
}
}
a[5](); // 5
//使用let,声明的变量仅在块级作用域内有效,最后输出的是5。
/* 输出: outer:0 outer:1 outer:2 outer:3 index:4,msg:undefined index:4,msg:undefined index:4,msg:undefined index:4,msg:undefined 原因: setTimeout的执行方式是异步执行 JavaScript 是单线程的,遇到setTimeout后会另开一条线程 执行setTimeout里的代码时,同步代码for循环已经执行完成 整个循环中只有一个i,i被for循环以及三个回调函数共用,循环结束后i=4,已经超出了原本数组的范围 把var 改成let */ var msg = ["This", "is", "a", "test"]; for(var i=0;i<msg.length;i++){ console.log("outer:"+i); setTimeout(function(){ console.log("index:" +i+",msg:"+msg[i]); },0); } /* 输出: outer:0 outer:1 outer:2 outer:3 index:0,msg:This index:1,msg:is index:2,msg:a index:3,msg:test 原因: let所声明的变量,只在let命令所在的代码块内有效,而且有暂时性死区的约束 暂时性死区:只要块级作用域内存在let命令,它所声明的变量就“绑定”(binding)这个区域, 不再受外部的影响 */ var msg = ["This", "is", "a", "test"]; for (let i = 0; i < msg.length; i++) { console.log("outer:"+i); setTimeout(function() { console.log("index:" + i + ",msg:" + msg[i]); }, 0); }
HTML 代码中使用全局变量
在 JavaScript 中, 全局作用域是针对 JavaScript 环境。
在 HTML 中, 全局作用域是针对 window 对象。
var 在全局域中声明的变量会成为window对象属性
let 在全局作用域中声明的变量不会成为window对象属性
var name="Matt";
console.log(window.name);//Matt
let age = 26;
console.log(window.age);//undefined
//但是let声明还是会在全局作用域中发生,相应的变量会在页面的生命周期内续存,
//所以为避免报错,必须确保页面不会重复声明同一个变量
const声明的特点
//1、const定义的变量不会预解析,必须先声明再使用,否则会报错
console.log(ccc);//err
const ccc=1;
//2.const声明后立即初始化
const PI;
PI = 3.1415;
console.log(PI);//err 而是应该立即初始化,const PI=3.1415
//3.const定义的变量不允许修改
const aa=5;
aa=6; //err
//4.不允许在相同作用域内重复声明同一个变量的
const PI = 3.1415;
console.log(PI);
const PI = 3.1415926;
console.log(PI);
//正确做法
const PI = 3.1415;
var s= 3*3*PI;
console.log(s);
//4.但在数组里面,const的值是允许被修改的,这是因为const存储的是地址,值的内容可以变化
const arr=[1,2,3,4,5];
arr[0]="cherry";
console.log(arr);//["cherry", 2, 3, 4, 5]
<body>
<p id="demo"></p>
<script>
//并非真正的常量
//const 的本质: const 定义的变量并非常量,并非不可变,它定义了一个常量引用一个值。
//使用 const 定义的对象或者数组,其实是可变的。下面的代码并不会报错:
//创建常量对象
const car={name:"li",age:"30",color:"red"}
//修改属性
car.color="green";
//添加属性
car.fruit="apple";
console.log(car);//{name: "li", age: "30", color: "green", fruit: "apple"}
document.getElementById("demo").innerHTML=car.fruit; //apple
//创建数组
const cars=["red","yellow","blue","black"];
//修改元素
cars[1]="pink";
//添加元素
cars.push("green");
console.log(cars);//["red", "pink", "blue", "black", "green"]
//显示数组
document.getElementById("demo").innerHTML=cars;//red,pink,blue,black,green
//但都不能对常量对象 常量数组重新赋值 会报错
try{
const car={name:"li",age:"30",color:"red"};
car={name: "li", age: "30", color: "green", fruit: "apple"};
}
catch(err){
document.getElementById("demo").innerHTML = err;
}
try{
const cars=["red","yellow","blue","black"];
cars=["red", "pink", "blue", "black", "green"];
}
catch(err){
document.getElementById("demo").innerHTML = err;
}
</script>
</body>


浙公网安备 33010602011771号