变量
什么是变量?
变量是计算机语言中能储存计算结果或能表示值抽象概念。
变量的定义
在ECMAScript 5.1版本及之前定义变量使用var 定义。例如:
var name = "EricXie"; name = "EricXie"; |
这里的var表示定义变量,name是变量的名称,也就是代表存储的抽象名称,等号后面的值就是存储的内容,这里的存储内容是EricXie这个字符串,因此用双引号引起来。
在JavaScript早期的版本中,变量是可以不用var来定义的,而是直接写:变量名=值的这种方法,虽然在程序中也是可以运行的,但是显然我们不能这么做,这样做不容易让我们分清,到底哪个是第一次定义变量的,哪一个后面的赋值。
变量的定义除了可以定义一个,也可以同时定义多个,例如:
var names="EricXie",age=28,sex="男"; |
或者:
var names="EricXie", age=28, sex="男"; |
注意:这里我们每个变量定义后面都是用逗号分隔,如果用分号,表示结束语句,而逗号表示可以连续定义多个变量。
变量在使用的时候我们通常需要减少重复定义相同的变量,而每次定义后仅使用一次,为了减少这种变量的定义,通常我们会在上面先定义一个变量,并不赋值,然后在后续的应用中每次使用这个变量赋值应用就可以了。例如:
var name; var age,sex; |
注意:如果你已经定义过一次,又一次定义的话,会覆盖上次定义的值,但是如果上次定义有值,这次定义没值,则本次是无效定义。例如:
var name="EricXie"; var name; //name="EricXie" |
JavaScript语言是一个弱类型语言,因此变量的定义并不需要严格数据类型,也就是说定义的变量是可以随时从一个类型更换到另外一个类型的例如:
var age=28;//数值 age="36";//字符 age=true;//布尔 |
关于数据类型我们在后面继续详细了解。但是从这个定义不难看出,变量可以随时更换存储的值,同时不限定存储值的类型。虽然给用户提供极其方便的定义模式,但是为后续的判断带来了麻烦,而且也影响了效率。
3、变量的名称
定义变量就需要牵扯到变量的起名,变量的起名是有要求的,必须英文字母和数字,下划线组成。为此我们在开发项目中通常起名时做了一些分类
例如:
- 无意义变量,循环等地方使用,很多使用i,j等单字母定义
- 多项无意义变量时,可以在后面加上数值,例如i1,i2等等
- 多用途变量 以英文名称定义,例如:speed
- 单一用途变量,以英文名称定义,复合型词组定义,除了第一个单词外,其它单词首字母大写,称为驼峰式命名例如:goodsList
- 如果需要指定某个更具体的归属时,可以用下划线分割,例如jd_goodsList
- 私有非暴露变量,或者带入函数中的参数名需要赋值给公有变量时,使用下划线开始,例如:_width。虽然在JavaScript中没有私有变量,但是有时候我们还是需要这种方法来处理的。
虽然上述已经做了开发中大家相互规定的变量名称方式,但是仍然还有很多人喜欢乱起变量,例如goods1,goods2,goods3等等,这种情况起始并不好,因为每一个变量占有一个变量的存储空间,如果希望将相似类型的数据进行存储变量,最好使用数组,关于这部分我们在后面的数组中介绍。
var goods1=1; var goods2=2; var goods3=3;
var goodsList=[1,2,3]; |
还有人用中文命名变量,虽然不会报错,但是我们仍然是禁止的。
var 名字="EricXie"; //禁止这样定义 |
当然还有一些符号没有说也是可以用的,例如$,这些符号和一个英文字符一样使用。但是注意使用的方式,jQuery就使用$,因此如果我们使用jQuery时,尽量避免单独使用$。
并且变量名称不能是一些保留字,关键字等。
关键字 Break do instanceof typeof case else new var catch finally return void continue for switch while function this with default if throw delete in try |
保留词 abstract int short boolean export interface static byte extends long super char final native class float throws const goto private double import public |
而且有些关键字虽然没有罗列出来但是它的类型却被默认了(天哪,不是说好的弱类型就是随便指定类型吗?)设置会引起很多反应,这些变量是什么?
例如:
var status=5; //字符型的5 |
为什么会出现这种情况。其实在JavaScript中认为变量就是对象的属性,例如定义在了页面中的变量,就会认为是window的属性,例如定义了下面的变量:
var goodsName="电脑"; console.log(window.goodsName);//电脑 |
从这里可以发现在页面中直接定义的变量起始就是window对象添加一个属性,这个属性在window下直接可以获取到。当然如果在后面使用了面向对象等内容,变量就是另外的问题了。
我们回到status这个变量,为什么我们定义了数值型的5,但是却得到了字符型的5.起始原因也是window的属性就是变量这个概念。Window这个对象下原本就有很多的属性,而且这些属性在系统中已经给与规定含义和类型的,例如这个status就是window.status属性,name就是window.name属性。所以这些属性都是强制保留了window自己给与的。因此我们定义了数值,他就会自动转换成规定的字符了。因此我们尽量避免与window下的属性和方法同名。
变量的内存存储
内存分为栈区(stack)和堆区(heap),然后在JavaScript中开发人员并不能直接操作堆区,堆区数据由JavaScript引擎操作完成
变量的定义在内存中包括三个部分:
-
- 变量标示 (变量标示存储在内存的栈区)
- 变量值 (比如上面中的age的值35或者是job对象的指向堆区地址atguigu这个地址,这个值也是存储在栈区)
- 对象 (比如上图中的对象,对象存储在堆区)
数据类型
JavaScript语言中每一个值都是一种数据类型,这里一共有6种类型
- 字符型 String
- 数值型 Number
- 布尔型 Boolean
- Undefined 未定义
- Null 空值,但是用typeof获取类型时看到object也就是对象型。
- 对象 Object
String字符类型
字符类型是所有用单引号或者双引号前后包含的类型
例如
var names="EricXie"; var sex="男"; var age='35'; var block='';//空字符 var info="I'm a programmer"; var error="I'm" a "programmer"//错误的,这里的a并没有被双引号引起,因此,a不是字符,而是变量名 var error="I'm 'a' programmer" |
从上面我们可以看到用双引号或者单引号都可以引起来,但是必须对称,不要前面用单引号,后面用双引号,而且双引号中不要再出现双引号,如果我们想把那个a引起来就需要使用单引号,或者外面使用单引号,a使用双引号,这样就可以了。
只要使用双引号或者单引号引起来,不管里面是什么,数值,字符等等,我们都把他看成字符类型,字符通常被用来表达一些展现或者状态的内容。很多字符组成的内容我们称为字符串。一般来说字符类型就是指单个字符或者字符串。
Number 数值类型
数值类型对于计算机来说就不是单纯的十进制数值了,它代表了更多的含义。不过不管是那种数值,都是可以完成我们的数学运算的。例如
var num=0.5;//小数; var sum=1200;//整数; var index=-10;//负数; var hex=0xFF;//16进制数,对应十进制255; var octal=067;//8进制数,对应十进制55; var scientific=5.6e+5;//科学计数法数56000; |
可以看到数值类型可以表现整数,小数,正数,负数。这里我们把有小数点的小数称为浮点数。因为是计算机所以我们有十六进制和八进制,分别用0x起头表示十六进制,0起头表示八进制,注意是数值0不是字母o。至于什么是十六进制和八进制我们在后面再来详细讲解。
同时我们也有科学计数法,5.6e+5就是5.6乘以10的5次幂,e+n是乘以10的n次幂,e-n是10的负n次幂,就是除以10的n次幂
所有的数值类型都是可以参与数学运算的。
NaN是非数值的意思,注意NaN也是数值类型,只不过说明该值不是数值。
console.log(typeof NaN);//number |
Boolean 布尔类型
在计算机中有一种特殊的类型,就是布尔值,实际上就是真和假,或者说对和错。
它的值域只有两个,值域就是取值范围,因此我们看到这个类型起始就是true和false两个值。定义的时候我们可以这样设置
var right=true; var error=false; |
Undefined 未定义类型
未定义类型的值就一个,因此定义的时候这样
var value=undefined; var val; |
如果给值为undefined或者不给值,都是让这个变量定义后是未定义。
未定义并不是确切的值,他只是说明当前的变量的一种状态。
表示的是一种没有价值的状态,这个时候这个变量不需要也不能参与到运算中。
Null 空类型
Null是空类型,无法用其他方式给与赋值,只有赋值为null时才是这种类型,其实null也是一种状态,就是给变量标识为一个空的状态,切除了这个变量和内存中所有数据的引用关系。
通过这个就可以看出,这个对象仍然在堆区,job这个变量值的地址指向了null,而不是指向对象的堆区地址。当再也没有变量中的地址值指向了堆中的这个对象时,垃圾回收车就会把这个对象回收掉,堆中就不会有这个存储了。
从上面可以看出来一般类型的变量我们通常不需要把它的值设置为null,只有对象类型的变量我们不再使用它时,就需要将它的值设置为null
Null也是Object对象类型
console.log(typeof null);//object |
Object 对象类型
对象类型比较复杂。我们在这里先简单做一些介绍
对象是一个整体,里面可以包含多项较为复杂的内容。我们认为万物皆对象,也就是所有的东西都是对象。比如张三就是对象,汽车就是对象,面包就是对象。那么不管任何对象它都具备一些特点特征,用来形容它的,我们把这些叫做属性。还有就是它可以做的,例如张三会编程,汽车可以开起来跑,面包会坏掉,我们把这些叫做方法。那么对象就是由若干属性和方法构成的集合体。例如
var job={ name:"谢天", lesson1:"java", lesson2:"H5", lesson3:"Python", info:"高薪就业" }; var school=job; |
如果要想获取这两个对象下的属性和值时,我们可以这样做
console.log(job.info); console.log(school["info"]); |
这两种形式都可以获取到对象下某个属性的值,例如这里我们使用job.info,用点语法的形式可以获取精确知道的属性的值
也可以用对象[“属性名”]这种关键字的形式获取,属性名是一个字符串的关键词,这种写法主要可以获取多个不相同的属性时用到。我们可以用变量的形式带入到这个属性名上。那么变量名改变,这个school[pro]不需要修改就可以获取了。例如:
var pro="info"; console.log(school[pro]); |
设置对象的属性值也是这种方法,例如
job.info="高薪就业,就业率高"; job["info"]="高薪就业,就业率高"; |
上面的job和school就是两个对象,他们在内存中的存储方式是下面样式。
通过上图我们可以看到这里有两个变量job和school,他们都指向了对象这个地址,也就是他们都是同一个对象,修改了其中一个就会引起另外一个的改变,我们把这种情况叫做引用,也就是job和school引用了堆中的对象。
例如:
job.lesson1="java和大数据"; console.log(school.lesson1);//"java和大数据" |
数据类型转换
转换为数值型
Number()
Number方法可以直接将字符型转换为数值型,但是如果字符串的内容中除了数值还有别的字符的话,就会转换为NaN,当然针对别的类型转换后也会出现一些不同的特点。请仔细记牢下面的转换结果。
var num0="10"; console.log(Number(num0));//10 var num1="3.1415"; console.log(Number(num1));//3.1415 var num2="10a"; console.log(Number(num2));//NaN var num3="a10"; console.log(Number(num3));//NaN var num4=true; console.log(Number(num4));//1 var num5=false; console.log(Number(num5));//0 var num6=undefined; console.log(Number(num6));//NaN var num7=null; console.log(Number(num7));//0 var num8={a:1}; console.log(Number(num8));//NaN |
parseInt()
parseInt是将任何内容转换为整型数值的方法。下面是转换的不同特点。虽然都是转换成数值,但是我们明显发现和Number有很大的区别,这里会把数值开始的所有字符串转换,当然遇到字符串就不转换了。如果纯字符串、布尔值、null都会转化为是NaN
var num0="10"; console.log(parseInt(num0));//10 var num1="3.1415"; console.log(parseInt(num1));//3 var num2="10a"; console.log(parseInt(num2));//10 var num3="a10"; console.log(parseInt(num3));//NaN var num4=true; console.log(parseInt(num4));//NaN var num5=false; console.log(parseInt(num5));//NaN var num6=undefined; console.log(parseInt(num6));//NaN var num7=null; console.log(parseInt(num7));//NaN var num8={a:1}; console.log(parseInt(num8));//NaN |
parseFloat()
parseFloat是转换为浮点数,也就是说除了不会把有小数点的内容转换为整数外,其它的和
parseInt是完全相同的。在这里我们就不罗列了。
转换为字符
String()
String是强制转换为字符串的内容,除了对象以外其它的所有内容在转换后都会直接转换为字符串,比如true就会转换为”true”,但是对象类型就会转换为[object Object]
var num8={a:1}; console.log(String(num8));//[object Object] |
toString()
toString是把所有内容转换为字符串,但是在这里有一个参数,如果不写默认转换为字符串,如果写入就会按照进制转换,例如写toString(2)就是转换为2进制的字符串,但是最多不超过36,否则就会报错。除此之外和String强转相同
var num1=15; console.log(num1.toString(2));//1111 var num2=15; console.log(num2.toString(8));//17 var num3=15; console.log(num3.toString(16));//f |
toFixed()
toFixed也是强转字符串,主要的特点,就是可以把数值按照小数点位置保留,例如我们可以把16变成16.00,在数值中是无法表现的,我们就可以通过这个方法来获取成字符串。其它的部分和String方法相同。这里后面的2就是2位小数,可以根据需求来设置保存不同位的小数。
var num1=15.00; console.log(num1.toFixed(2)); |
+””
通常我们有一个最简单的办法可以将任何内容转换为字符串,那就是用+“”
例如
var num1=15; console.log(num1+"");//"15" var num2=true; console.log(num2+"");//"true" |
转换为布尔型
Boolean()
可以将任何内容转换为boolean,因为我们的程序中条件语句主要是通过结果的布尔值判断是否进入条件的执行语句,因此下列的转换非常重要。
我们发现数值型的NaN和0,字符型的””空字符串,undefined,null在强转后都是false,除此之外的所有内容转换都是ture
var num0=NaN; console.log(Boolean(num0));//false var num3=0; console.log(Boolean(num3));//false var num5=""; console.log(Boolean(num5));//false var num6=undefined; console.log(Boolean(num6));//false var num7=null; console.log(Boolean(num7));//false var num1=1; console.log(Boolean(num1));//true var num2=-1; console.log(Boolean(num2));//true var num4="abc"; console.log(Boolean(num4));//true var num8={a:1}; console.log(Boolean(num8));//true var num9={}; console.log(Boolean(num9));//true |
隐式转换
JavaScript是一种弱类型语言,也就是变量的类型随着给的值而自动变化。那么具体变成什么类型就要看做了什么运算。关于这个问题,我们在后面再来继续讲解。这里说的隐式转换就是指后面的运算中,需要将两个不同类型运算就需要先将其中一个做隐式转换然后再根据规则运算出结果。
那么我们的隐式转换是如何转换的呢,其实隐式转换就是我们前面讲过的。
- 隐式转换为数值型===Number()
- 隐式转换为字符型===String()
- 隐式转换为布尔型===Boolean()