变量是用于保存数据的内存空间,什么意思呢,可以把变量理解为一个框,这个框可以放一个数据,例如放一个整型,放一个对象这些,有了变量之后,我就可以把数据存起来,方便后续处理。
JS 这种弱类型语言的变量其实是非常好用的,在强类型语言中,他有很多类型的变量,每一种类型的变量只能存储指定的值,例如整型变量只能存整数,浮点型变量只能存小数,字符型变量只能存字符,这一点都不灵活,但 JS 不一样,JS 就一个变量,啥都能存,非常灵活,这就是弱类型语言的一个优势。
首先,你要使用变量,首先你得有变量吧,变量本身是一块内存空间,那我们就应该先开辟一个空闲的内存空间,这个开辟空闲内存空间的过程叫做声明。
js
var a;这里就开辟了一个名字叫 a 的变量,很简单对吧。
有了这样一个变量之后,我们就可以往这个变量里放东西了。
js
var a;
a = 1;//把1放进这个变量
console.log(a);//直接把变量a输出我们把 1 存入变量,这个把一个数据存入变量的操作,我们称为赋值,对一个变量第一次的赋值的操作我们称为赋初值,当我们要使用这个变量的值的时候也很简单,直接写变量名就 OK ,这里就会输出 1。
值得注意的是,这个 = 并不读作等于读作等于,而应该读作赋值,在程序语言中,真正的等于应该是== 这样的两个等号,对于
a = 1这个操作,我们应该读为把 1 赋值给变量 a
下面考虑不赋值直接输出
js
var a;
console.log(a);这里会输出 undefined,所以,对于一个只声明没有赋值的变量,其值为 undefined。
在大多数时候,变量声明出来就得有一个初值,如果我声明和赋初值操作写成两条语句稍显啰嗦,所以我们可以简化写法。
js
var a = 1;
console.log(a);这里的 var a = 1 其实就是声明+赋初值的简化写法,可以在声明的时候赋初值。这是一个典型的语法糖,语法糖就可以理解为一个简便写法,声明的赋初值这两个操作本来需要写两个语句,这里 JS 提供了这样一个语法糖来简化为一句,编程语言提供的这种简便写法就叫做语法糖。
语法糖本质上只是一个简便写法,并不是提供一个新功能,例如这里的声明并赋初值的语法糖,本来两句话比较麻烦,JS 提供了一个新的写法让我们一句话就就可以完成,这就叫语法糖,虽然我们可以这么写,但实际运行的时候还是把它拆成两个步骤来的,和原来的写法是完全等价的。
除此之外,我们还可以批量声明变量。
js
var a,b,c,d;
a = 1;
b = 2;
c = 3;
d = 4;
console.log(a,b,c,d);这里的 var a,b,c,d; 其实就是一次性批量声明了四个变量,并且后面紧接着给四个变量赋初值,然后输出,这也是一个语法糖。
这里的
console.log(a,b,c,d)和前面的写法不太一样,前面的写法里console.log()里面都只有一个值,这里传入多个值实际上就是依次输出的,相信读者自己试验一下也能看出来
当然,我们可以看到这样在下面一个一个赋初值也显得很麻烦,对于批量声明并给多个变量赋初值的操作,我们依然可以简写
js
var aa = 1,bb = 2,cc = 3,dd = 4;
//如果你和我一样觉得这样写在一行不好看,你也可以写成这样
var a = 1,
b = 2,
c = 3,
d = 4;这样就可以实现在批量声明的过程中给多个变量赋初值,简单吧。
js
var a = 1;
console.log(a);
a = 2;
console.log(a);以上代码会输出 1 和 2,显然,变量的值是可以被重新赋值的,并且新值会覆盖旧值。
对于值不可改变的量,我们称为常量,在 ES5 标准中并不原生支持常量,只有通过一些特定手段来实现常量等效的效果,不过在 ES 6 中已经支持常量了。
再来看一个很神奇的效果
js
var a = 1;
console.log(typeof a);
a = "test";
console.log(typeof a);如果读者有过一些其他强类型语言的编程基础,会认为这个代码根本无法执行,因为 a 的值一会儿是数字,一会儿是字符串。但在 JS 中,a 的值类型都是可以变化的,也就是说在 JS 中我们其实无需关心一个变量的数据类型,只要这是一个变量,它就可以存储任何类型的数据。
在 JS 中你甚至可以声明多个同名变量,这与其他语言不太一样,在 C 语言中,声明一个已经存在的同名变量是不被允许的,在 JS 中是可以的。
任何可以放数据的地方,都可以放变量。
js
var a = 1;
var b = 2;
console.log(a,b);
b = a;
console.log(a,b);在这个语句中我先声明了 a 和 b 两个变量,并给了初值,然后将 a 变量的值赋值给 b 变量,此时 a 和 b 变量的值应该均为 1
变量也可以用来存引用类型
js
var a = {
name:"YY",
age:12,
isVip:true
}
console.log(a);变量必须要声明之后才可以使用,如果使用一个没有声明的变量,会直接报错。
js
console.log(a);//报错虽然我们说不能使用未声明的变量,但是这里有一个例外,就是
typeof操作符,我们是可以对一个未经声明的变量使用typeof操作符,并且不会报错,会获得undefined
变量提升
变量提升是比较深入的知识点,在预编译部分会介绍到,这里简单了解,JS 中存在变量提升,变量提升就是所有的声明操作都会自动提升到变量的最顶部,我们举个例子:
js
console.log(a);
var a = 1;在这个例子中,第一行代码输出a,按道理说,JS应该是从上往下执行的,执行到这里的时候a这个变量并没有声明,所以按道理说是报错,但实际上并不是这样,这里会输出undefined,这就是因为变量提升,所有的声明会提升到到顶部,也就是说var a这个操作会被提升到顶部率先执行,这就让执行console.log(a)的时候,a变量实际上已经被声明了,也就不会报错,会返回undefined。
提升的只有变量声明,并不包含变量赋值,var a = 1这句话本就是两条语句共同组成,即var a和a = 1,变量提升只会把var a提升,并不会把a = 1提升到顶部。
以上介绍了变量的基本使用方法,我们都是把变量取名为 a, aa 这类没有实际含义的单词,但实际开发中这些变量名称都是有实际含义的,变量名的命名原则就是,别人一看到你的变量名就能知道你这个变量是用来干嘛的。那这里有一个问题,是不是任何单词或者字符都可以作为变量名呢,显然是不可以的,例如这行代码 var var = 1 这行代码是绝对错误的,我们不能定义一个名字叫 var 的变量,下解释原因。
在开发中,凡事需要自行命名的位置都叫做标识符,比如变量名就是一个典型的标识符,标识符的名字并不可以随便取,需要符合一定规范。
标识符的命名规范
- 只能由英文字符、下划线、$、数字组成
- 不能以数字开头
- 不能为关键字和保留字
在标识符的命名规范里,JS 和其他语言有一个不同的地方,就是美元符,在其他语言中,比如 C 语言,都没有说美元符可以用作标识符,但是 JS 可以,这一点需要注意一下。还要值得注意的是,如果读者比较有实践精神,去试验一下,会发现这个命名规范似乎是错误的,好像不用按照这个命名规范也可以,确实, 例如这句代码:var 张云凌 = 1,是没有任何问题的,也就是说这个变量名完全可以是中文,但依旧不建议这样使用,这可能会导致一些兼容性问题。
在命名规范中的第三点提到了关键字和保留字,这里做简单解释
- 关键字:在 JS 中有特殊含义或者作用的单词我们称为关键字,例如
var就用来声明变量,我们不能以关键字作为变量名,假如我们允许使用关键字作为变量名,那么当我写一个var的时候就会产生歧义,有可能是声明变量,也有可能是表示名为var的变量,这种具有歧义的情况显然是不被允许的。 - 保留字:在 JS 中目前不是关键字,但未来有可能作为关键字,JS 也将其保留下来,不允许作为标识符。
[!node] 不写 var 的变量 在 JS 中,变量声明其实可以不用写
var关键字,即直接通过a = 1这样的语法进行赋值操作,如果 a 变量没有被声明过,直接写a = 1,等价于window.a = 1。
在这里我们可以看到写不写var其实都一样,但在后面学习了定义域之后,我们会发现写不写var的区别其实非常大,虽然可以不写var,但在实际开发中都必须写上,这是开发规范的问题。
驼峰命名法
驼峰命名法是程序设计中变量的常见命名方式,这个命名规则适用于任何编程语言,驼峰命名法的原则就是,每一个单词的首字母大写,就是这么简单,驼峰命名法又分为小驼峰和大驼峰,其区别就是,小驼峰的首字母小写,大驼峰的首字母大写。
我要使用一个变量来表示文字大小,如果使用小驼峰可命名为 fontSize,如果使用大驼峰则命名为 FontSize。
除了驼峰命名法以外,还有一种下划线的命名方式,即 font_size,这也是常用的命名方式,不管是小驼峰,大驼峰还是下划线,按照个人喜好选择即可。
| 关键字 | 含义 |
|---|---|
| break | 跳出 循环 |
| continue | 继续 |
| case | 捕捉 |
| default | 配合switch,当条件不存在时使用该项 |
| if | 用来生成一个条件测试,如果条件为真,就执行if下的语句。 |
| else | 否则//配合if条件判断,用于条件选择的跳转 |
| switch | 弥补if的多重判断语句 |
| for | (循环语句) |
| in | 1.配合for遍历对象,2.判断某个属性属于某个对象 |
| do | 用来声明一个循环,这个循环的结束条件可以通过while关键字设置 |
| while | (循环语句) |
| try | 接受异常并做出判断Abstract 抽象的// 配合catch进行错误判断 |
| catch | 配合try进行错误判断 |
| finally | 预防出现异常时用的,无论异常是否是否发生异常都会处理的 |
| throw | 投、抛出异常 |
| var | 声明变量 |
| void | 空/ 声明没有返回值 |
| function | 定义函数的关键字 |
| return | 返回 |
| new | 创建一个新对象 |
| this | 总是指向调用该方法的对象 |
| typeof | 检测变量的数据类型 |
| instanceof | 某个对象是不是另一个对象的实例 |
| delete | 删除了一个属性 |
| with | 语句用于设置代码在特定对象中的作用域 |
| true | 真 |
| false | 假 |
| 保留字 | 含义 |
|---|---|
| abstract | 表达抽象类 |
| boolean | 对象用于将非布尔值转换为布尔值 |
| byte | 字节 |
| char | 字符Java语言的一个关键字,用来定义一个字符类型 。 |
| class | 定义“类” |
| const | 声明一个只读的常量,一旦声明,常量的值就不能改变 |
| debugger | 语句用于停止执行 JavaScript,并调用 (如果可用) 调试函数。 |
| double | 双精度浮点型 |
| enum | 枚举 |
| export | 可以输出一个模块,可以是变量或者方法 |
| extends | 用来创建一个普通类或者内建对象的子类。 |
| final | 修饰用的关键字 |
| float | Float() 函数可解析一个字符串,并返回一个浮点数 |
| goto | 无条件转移语句 |
| implements | 实现相应接口的方法 |
| import | 用于导入由另一个模块导出的绑定 |
| int | 整数类型 |
| interface | 将一个数值向下取整为最接近的整数的函数 |
| long | 表示一种长整型数据,是编程语言中的一种基本数据类型,为long int 的缩写,默认为有符号长整型 |
| native | 表示一种长整型数据,是编程语言中的一种基本数据类型,为long int 的缩写,默认为有符号长整型 |
| package | 属性是 Java 解释器所知道的所有包的根 |
| private | 内部变量private;@private标签标记标识符为私有 |
| protected | 创建实用程序函数 |
| public | 全局变量 |
| short | 短整型 |
| static | static的变量称为静态变量或类变量 |
| super | super() 函数是用于调用父类(超类)的一个方法 |
| synchronized | 实例对象锁 |
| throws | 将异常抛给调用者可以使程序能够继续执行下去 |
| transient | 一种持久化对象实例的机制 |
| volatile | 作为指令关键字,确保本条指令不会因编译器的优化而省略,且要求每次直接读值 |