JavaScript的类型、值和变量

  计算机程序的运行需要对值进行操作,在编程语言中,能够表示并操作的值得类型称为数据类型。变量用来将值存储起来,变量是值得符号名称。

一、数据类型

  JavaScript的数据类型可以分为两类,原生类型和对象类型,JavaScript的原始类型包括数字、字符串和布尔值,JavaScript还有两个特殊的原始值null(空)和undefined(未定义),它们不是数字、字符串和布尔值。对象类型包含普通对象、数组、函数、日期、正则、错误对象。

  JavaScript的类型也可以按有无方法分,除了null和undefined,其他的类型都是拥有方法的值,字符串、数字、布尔值在使用方法时,会临时转化为对应的对象。

  JavaScript的类型也可以可变类型和不可变类型,只有对象和数组属于可变类型,其他的都是不可变类型,包括字符串。

二、JavaScript的内存管理机制

  JavaScript解释器有自己的内存管理机制,可以自动对内存进行垃圾回收。这意味着程序员可以按需创建对象,程序员则不必担心这些对象的销毁和内存回收,当不再有任何引用指向一个对象,解释器就会知道这个对象没用了 ,然后就自动回收它所占的内存资源。 

三、数值

  a、JavaScript中数值有整型和浮点型

  整型可以用十进制和十六进制(0xff).

  浮点型可以包含小数点,可以采用传统写法,还可以使用指数计数法。

  3.14

  6.02e23  //6.02x1023

  6.02E-23  //6.02x10-23

  b、JavaScript中的算术运算

  JavaScript运算符包括+、-、*、/、%(求余).除了基本的运算符外,Javascript还支持更复杂运算。这些运算和Math对象的属性和方法有关。

  Math对象的属性

  

  Math对象的方法

  

    例子:

  

        Math.round(Math.random()*10)           //返回0到10(包含0和10)的整数

  溢出当数值超出了JavaScript所能表示的数字上限(溢出),结果为一个无穷大值。表示为Infinity。

     当负数超出了JavaScript所能表示的负数范围,结果为负无穷大。表示为-Infinity。

     基于无穷大的加减乘除让是无穷大,保留其原来的符号。

  下溢:当运算结果无限接近0且比JavaScript所能表示的最小值还小时发生下溢。这种情况下JavaScript返回0。正数下溢返回0;负数下溢返  回-0;0和-0几乎没有区别(除了作为除数)。 

1   var  a=0;
2   var  b=-0;
3   console.log(a===b);  //true
4   console.log(1/a===1/b) //false

 

  被0整除并不会报错。  

1 var  a=1;
2 console.log(a/0);  //Infinity
3 console.log(a/-0); //-Infinity
4console.log(0/0) //NaN

  NaN(not -a-number)://表示不是一个数字

  0/0、无穷大除无穷大、给负数开偶次方、算术运算符的操作数不是一个数字或者无法转化成数字(+运算符特殊)。

1 console.log(0/0);  //NaN
2 console.log(Infinity/Infinity); //NaN
3 console.log(Math.sqrt(-3))   //NaN
4 console.log('a2'-3); //NaN

  Infinity和NaN是JavaScript中定义的全局变量。

  NaN和任何值都不相等,包括自身。所以判断一个值x是不是NaN,应使用x!=x。

  isNaN是一个全局函数。可以用来判断一个数字是不是NaN,如何一个是NaN或者不能转换成一个数字,返回true. 

1 console.log(isNaN([]));  //false
2 console.log(isNaN('3'))  //fase
3 console.log(isNaN('ab'))  //true

   isFinity()也是一个全局函数。当参数是NaN(转化成数字),-Infinity,Infinity的时候,返回false.其他时候都是返回true. 

1 console.log(isFinite(Infinity));  //false
2 console.log(isFinite(NaN))  //false
3 console.log(isFinite('ab'))  //false

 

四、字符串

  字符串一个一组不可变字符组成的序列,字符串的字符索引从0开始,字符串的长度是其所包含的字符的个数,空字符的长度为0.

  字符串直接量要用单引号或者双引号括起来,字符换换行用反斜线\连接。

  ‘’\'在字符串中有着特殊用途,'\'+字符会改变字符原来的意思。'\n'代表换行,这类字符称作转义字符。

  

五、布尔值

  布尔值指代真或假,只有两个值true和false。JavaScript中比较运算通常返回的都是布尔值。

  a=1;b=2;

  a==b;//返回false

六、null和undefined  

  null是JavaScript中的关键字。常用来表示空值。typeof null会返回"object".实际上null是它自有类型的唯一值。他表示数字、字符串、对象是无值的。

  undefined是JavaScript中的全局变量,表示变量的值没有初始化。typeof undefined返回"undefined"。是它自有类型的唯一成员。  

1 console.log(typeof null); //object
2 console.log(typeof undefined); //undefined 

  ==运算符认为他两个是相等。

七、全局对象

  全局对象的属性是全局定义的符号,JavaScript可以直接使用。当JavaScript解释器启动时,他会创建一个新的全局对象,并给他一组定义的初始属性。

  全局属性:undefined、Infinity、NaN等

  全局函数:isNaN()、eval()等

  构造函数:Date()、Array()等

  全局对象:Math、JSON

  全局对象的初始属性不是保留字,但是应该当做保留字对待。

  在最顶级代码中,可以使用this关键字引用全局对象。全局对象定义了JavaScript中的所有的预定义全局值。这个特殊对象同时包含了程序定义的全局值(用户自定义的全局变量)。

 八、包装对象

  JavaScript中的数字、字符串、布尔值也可以调用方法。这些原始值在调用方法之前会通过对应的构造函数转化成对象,调用对象的方法(属性),对象会自动销毁。 

1 var s="s";
2 s.len=4;//给它设置属性
3 console.log(s.len);//undefined

  null和undefined没有包装对象。访问它们的属性会报错。

 ==认为包装对象是相等的,而===认为他们是不等。

  typeof可以看出其中的差别。 

1 var s="s";
2 var S=new String(s)
3 console.log(typeof s);//"string"
4 console.log(typeof S);//"object"

 

九、不可变的原始值和可变的对象引用

  原始值是不可变的。通过字符串的方法修改字符串返回一个新的字符串,而字符串的原始值并没改变。 

1 var s="sdasd";
2 console.log(s.toUpperCase());//"SDASD"
3 console.log(s);//"sdasd"

 

  原始值得比较是值得比较。例如字符串只要长度相等,对应位置的字符相等,则认为它们是相等。

  对象和原始值不同,对象的值是可变的。

1 var obj={
2     a:1,
3     b:2
4 }
5 obj.a=3;
6 console.log(obj.a);  //3

  对象的比较不能通过值来比较,即使两个对象同样的值属性且属性值相等。它们也是不相等。

  变量存储的是对象的引用值,即对象在堆中的地址。只有引用值相等。才能认为两个对象是相等。

十、类型转换

  a.隐式类型转化

  JavaScript中的取值类型非常灵活,可以根据需要自动转化类型。

  

  对象转换成布尔值:所有的对象都会转换成true;new Boolean(false)对象也会转换成true.

  对象转换成数字和对象转换成字符串:这里提到到转换方法只适合于本地对象(宿主对象(Web浏览器定义的对象)有自己的转换规则)。所有的对象都继承了两个转化方法。

  第一个是toString()方法:默认的toString()方法用来返回对象的类型。

1 var obj={
2     a:1,
3     b:2
4 }
5 console.log(obj.toString());  //[object object]

  日期对象、数组、函数、正则对象的toString()方法。

1 console.log([1,2,3].toString());    //1,2,3
2 console.log(new Date().toString())     //Wed Mar 07 2018 02:01:18 GMT+0800 (中国标准时间)
3 console.log(function(){return 0;}.toString()) //function (){return 0;}
4 console.log(/\d+/i.toString())  // /\d+/i

  第二个方法时valueOf().如果对象存在原始值。则这个方法返回原始值,大多数对象无法还原成原始值,valueOf()简单返回对象本身。数组、函数、正则对象的valueOf()方法返回对象本身。而日期对象的valueOf()返回的是1970.1.1到现在的毫秒数。 

1 console.log(new Date().valueOf())     //1520359837257

  JavaScript中的对象转换成字符串:--如果对象有toString()方法,调用这个方法返回一个原始值,再把原始值转换成字符串。

                   --如果对象没有toString()方法,或者这个方法返回的不是一个原始值,则调用valueOf(),调用这个方法返回一个原始值,再把原始值转换成字符串

                   --如果不能通过上述的两个方获得原始值,则抛出一个类型错误。

  JavaScript对象转换成数字:和转发成字符串的方法类似,不过先调用valueOf()方法获得原始值,转换成数字。

  +、==、!=、关系运算符(>、<)中对象到原始值的转换:先调用valueOf(),在调用toString()。得到的原始值直接使用。

  +、==操作日期对象时转化成数字、字符串:先调用toString(),在调用valueOf(),得到原始值直接使用。 

1 var  now=new Date();
2 console.log(now==now.toString());//true  先调用toString()
3 console.log(now+1)              //Wed Mar 07 2018 02:37:30 GMT+0800 (中国标准时间)1  先调用toString()
4 console.log(now>now-1)          //true  先调用valueOf()

  b、显示类型转换

  转换成数字:Number()函数、ParseInt()、ParseFloat()

  Number()只能基于10进制进行转换,不能出现非法的尾随字符:

  ParseInt()用于整型:可以忽略前导空格、尽可能多的解析更多数值,忽略后面的内容,不能转换返回NaN

  ParseFloat()整型和浮点型 可以忽略前导空格、尽可能多的解析更多数值,忽略后面的内容,不能转换返回NaN

  

   parseInt可以接受第二个参数,这个参数指定数字的基数(2~36)。

  

  转换成字符串:String()、toString()

  String()函数会把null、undefined转换成空对象,而toString()方法会报错。

  toString()在用于数字到字符串的转换时,可以在参数中输入数的基数,表示数字是几进制的。  

1 var n=12;
2 console.log(n.toString(16));//c

 

  toFixed()、toExponential()、toPrecision()也可以用于数字到字符串的转换;

  toFixed(arg):参数用来指定小数的位数

  toExponential(arg):使用指数计数法表示数字,小数点前只有一位,参数指定了小数点后的位数

  toPrecision(arg):arg指定有效数字的位数,如果有效数字的位数少于整数部分的位数,则使用指数表示。

  以上的三个方法会进行四舍五入和补0操作。  

1 var a=123456.789
2 console.log(a.toFixed(0)) //"123457"
3 console.log(a.toFixed(1)) //"123456.8"
4 console.log(a.toFixed(5)) //"123456.78900"
5 console.log(a.toExponential(2)) //"1.23E5"
6 console.log(a.toExponential(3)) //"1.235E5"
7 console.log(a.toPrecision(3))  //"1.23e5"
8 console.log(a.toPrecision(7))  //"123456.8"

  转换成对象:Object()

  转换成布尔值:Boolean()

十一、变量声明

  a、用var关键字声明变量:

  var x,y;  var x=1,y=2;

  声明的变量没有初始化之前的值是undefined.

  可以使用声明一个变量多次,但是不能使用未声明的变量。不使用var关键字声明的变量是全局变量,无论位置。不用var声明的变量可以用delete 删除。

  b、全局变量和局部变量

  全局变量拥有全局作用,局部变量只在函数内可见,函数体局部变量的优先级高于全局变量。 

  c、变量声明提前

  在函数中变量的声明前就可以用,变量的声明就好像放在函数的最前面一样。 

1 (function(){
2     console.log(a);//undefined
3     var a=0;
4     console.log(a);//0
5 })();

 十二、作用域链

  JavaScript中规定全局变量是全局对象的属性,可以通过this关键字引用全局变量。而局部变量是与函数调用相关的某个对象的属性,JavaScript中没有办法引用该对象。作用域链是一个链表,上面存放了当前位置代码可访问的变量的保存对象。JavaScript需要访问某个变量时,它会在作用域链的对象上查找是否有该属性,直到找到该属性,否则会报错。

  函数在定义的时候保存一个作用域链,当函数调用的时候,创建一个对象用来保存函数内部的局部变量,然后把对象添加到作用域链上,同时创建一个新的更长的函数调用链。当函数有嵌套函数时,函数每次调用时内部函数的作用域链都是不同的。 

posted @ 2018-03-04 16:30  Skd一路花开  阅读(356)  评论(0编辑  收藏  举报