JavaScript笔记1——类型、值和变量

JavaScript的数据类型分为两类:原始类型和对象类型。
原始类型包括数字、字符串和布尔值、null(空)和undefined(未定义)。在JavaScript中,只有null和undefined是无法拥有方法的值。
对象是属性(property)的集合,每个属性都由“名/值”对构成(值可以是原始值,比如数字、字符串,也可以是对象)。
 

一、数字

当一个数字直接出现在JavaScript程序中,我们称之为数字直接量,浮点型直接量可以含有小数点,此外,还可以用指数记数法表示浮点型直接量,即在实数后跟字母e或E,后面再跟正负号,其后再加一个整型的指数,这种计数方法表示的值,是由前面的实数乘以10的指数次幂。

6.02e23 //6.02 x 10^23
1.478E-32 //1.478 x 10^-32

被0整除在JavaScript中并不会报错,它只是简单地返回无穷大(Infinity)或负无穷大(-Infinity),0除以0返回NaN
isNaN():参数为NaN或一个非数字值(比如字符串和对象),则返回true
isFinite():在参数不是NaN、Infinity或-Infinity的时候返回true

0 === -0

isNaN(2) //false
isFinity(2) //true
1/0 === 1/-0 //false,正无穷大和负无穷大不等

二、文本

在JavaScript程序中的字符串直接量,是由单引号或双引号括起来的字符序列。
在JavaScript程序中,反斜线(\)有着特殊的用途,反斜线符号后加一个字符,就不再表示它的字面含义了,我们称之为转义字符

\o        NUL字符
\b        退格符
\t        水平制表符
\v        垂直制表符
\n        换行符
\f        换页符
\r        回车符
\"        双引号
\'        单引号
\\        反斜线
\xXX      由两位十六进制数XX指定的Latin-1字符

\uXXXX    由4位十六进制数XXXX指定的Unicode字符

var s = "hello,world"
s.length             // 11
s.charAt(0)          //"h"
s.substring(1,4)     //"ell"
s.slice(1,4)         //"ell"
s.slice(-3)          //"rld"
s.indexOf("l")       //2
s.lastIndexOf("l")   //9
s.split(",")         //["hello", "world"]
s.replace("h","H")   //"Hello,world" 替换第一次出现的字符
s.toUpperCase()      //"HELLO,WORLD"

三、布尔值

下面这些值会转换成false:
undefined
null
0
-0
NaN
"" //空字符串
false和上面6个可以转换成false的值有时被称作“假值”,其他值称作“真值”。

四、null和undefined

对null执行typeof,结果返回字符串"object",可以将null认为一个特殊的对象值,含义是”非对象“

undefined表示值的空缺,表明变量没有初始化。

null == undefined     //true
null === undefined    //false

你可以认为undefined是表示系统级的、出乎意料的或类似错误的值的空缺,而null是表示程序级的、正常的或在意料中的值的空缺。如果你想将它们赋值给变量或者属性,或将它们作为参数传入函数,最佳选择是使用null。

五、包装对象

JavaScript对象是一种复合值:是属性或已命名值的集合,通过o.m来引用属性,当属性值是一个函数的时候,称其为方法,通过o.m()来调用对象o中的方法。

var s = "hello,world";
s.length             // 11

字符串既然不是对象,为什么它会有属性呢?只要引用了字符串s的属性,JavaScript就会将字符串通过调用new String(s)的方式转换成对象,这个对象继承了字符串的方法,并被用来处理属性的引用,一旦属性引用结束,这个新创建的对象就会销毁(其实在实现上并不一定创建或销毁这个临时对象,然而整个过程看起来是这样),这个临时对象就称作包装对象。
可通过String()、Number()、Boolean()构造函数来显式创建包装对象

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

JavaScript中的原始值(undefined、null、布尔值、数字和字符串)与对象(包括数组和函数)有着根本的区别:原始值是不可更改的。
字符串中所有的方法看上去返回了一个修改后的字符串,实际上返回的是一个新的字符串

var s = "hello";
s.toUpperCase();   //返回"HELLO",但并没有改变s的值
s                  //"hello"

对象和原始值不同,首先,它们是可变的————它们的值是可以修改的。
我们通常将对象称为引用类型,对象值均是引用,对象的比较均是引用的比较。

七、类型转换

1、原始值到对象的转换

通过调用String()、Number()或Boolean()构造函数,转换为它们各自的包装对象

2、转换和相等性

如果在期望使用布尔值的地方使用了undefined,它将会转换为false,但这并不表明undefined == false,if语句将undefined转换为false,但"=="运算符从不试图将其操作数转换为布尔值。

如果比较的两者中有bool,会把 bool 先转换为对应的 number,即 0 和 1。

undefined == false //false

3、显式类型转换

除了null和undefined之外的任何值都有toString()方法,如果试图把null或undefined转换为对象,则会抛出一个类型错误。Object()函数在这种情况下不会抛出异常,它仅简单地返回一个新创建的空对象


JavaScript中的某些运算符会做隐式的类型转换。如果"+"运算符的一个操作数是字符串,它将会把另外一个操作数转换为字符串。一元"+"运算符将其操作数转换为数字。同样,一元"!"运算符将其操作数转换为布尔值并取反。
+x //等价于Number(x),也可以写成x - 0
toFixed():根据小数点后的指定位数将数字转换为字符串,它从不使用指数计数法。
toExponential():使用指数计数法将数字转换为指数形式的字符串,其中小数点前只有一位,小数点后的位数则由参数指定。
toPrecision():根据指定的有效数字位数将数字转换成字符串,如果有效数字的位数少于数字整数部分的位数,则转换成指数形式。

var n = 123456.789;
n.toFixed(2)          //"123456.79" 
n.toExponential(2)    //"1.23e+5"
n.toPrecision(2)      //"1.2e+5"

Number():将字符串转换为一个整数或浮点数直接量,这个方法只能基于十进制数进行转换。
parseInt():只解析整数,如果字符串前缀是"0x"或"0X",将其解释为十六进制数。
parseFloat():可以解析整数和浮点数。
parseInt()和parseFloat()都会跳过任意数量的前导空格,尽可能解析更多数值字符,并忽略后面的内容,如果第一个非空格字符是非法的数字直接量,将最终返回NaN。

parseInt("3 hdak")      //3
parseFloat("3.14 hdak") //3.14
parseInt("0xff")        //255
parseFloat(".1")        //0.1
parseInt(".1")          //NaN

4、对象转换为原始值

对象到布尔值的转换非常简单:所有的对象(包括数组和函数)都转换为true,对于包装对象亦是如此:new Boolean(false)是一个对象而不是原始值,它将转换为true。

所有的对象继承了两个转换方法:toString()和valueOf()
 toString()的作用是返回这个对象的字符串。例如:

console.log(({x:0,y:1}).toString());  // "[object object]"

很多类定义了更多特定版本的toString()方法。例如,数组类的toString()方法把数组中的每个元素转换为用逗号合并的字符串,函数类的toString()方法返回这个函数实现定义的方式,也就是说将用户定义的函数转换为JavaScript源代码字符串,日期类的toString()方法返回一个可被JavaScript解析的日期和时间字符串,正则类的toString()把正则对象转换正则表达的字符串格式。

console.log(({x:0,y:1}).toString());            //"[object object]"
console.log([1,2,3].toString());                //  1,2,3
console.log((function(x){f(x);}).toString());   //  "function(x){f(x);}"
console.log(new Date(2017,1,14).toString());    //输出Tue Feb 14 2017 00:00:00 GMT+0800 (中国标准时间)
var pattern=/\d+/g;
console.log(pattern.toString());               ///\d+/g

valueOf()方法的任务并未详细定义:如果存在任意的原始值,它就默认将对象转换为它的原始值。对象时复合值而且大多数对象无法真正表示一个原始值,因此默认valueOf()方法简单地返回对象本身,而不是返回一个原始值。数组、函数、正则表达式都继承了这个默认方法,调用这些类型实例的valueOf()方法只是返回对象本身。日期类对象的valueOf()方法一个它的内部表示,从1970年1月1日以来总的毫秒数。例如:

console.log(({x:0,y:1}).valueOf());//输出Object {x: 0, y: 1}

console.log([1,2,3].valueOf());//输出 [1, 2, 3]

console.log((function(x){f(x);}).valueOf());//输出function (x){f(x);}

var d=new Date(2017,1,14);
console.log(d.valueOf());//1487001600000

var n=new Number(1); 
console.log(n.valueOf());//输出1

var b=new Boolean(false);
console.log(b.valueOf());//输出false

var str=new String("str");
console.log(str.valueOf());//输出str

需要注意的特殊转换:

var n=new Number("a"); 
console.log(n.valueOf());//NaN

var b=new Boolean("str");
console.log(b.valueOf());//输出true

通过上面的介绍的toString()和valueOf()方法,就可以做到对象到字符串和对象到数字的转换了。但需要注意的是某些特殊场景(+、-、*、==、!= 、>、<)中JavaScript执行了完全不同的对象到原始值的转换。 总的而言,在JavaScript中对象到字符串的转换经过如下步骤: 
1) 如果对象具有toString()方法,则调用这个方法。如果返回一个原始值,JavaScript将这个值转换字符串,并返回这个字符串的结果。 
2)如果对象没有toString()方法或者这个方法并不是返回一个原始值,那么JavaScript会调用valueOf()方法。如果存在这个方法,JavaScript调用它。如果返回值是原始值,将这个值转换为字符串,然后返回。 
3)如果无法从toString()和valueOf()获得一个原始值,此时就会抛出一个类型错误。

在对象到数字的转换过程中,JavaScript做了同样的事情,只是它首先尝试调用valueOf()方法。 
1)如果对象具有valueOf()方法,并返回一个原始值,则JavaScript将这个原始值转换为数字,并返回这个数字。 
2) 否则,对象尝试去调用toString()方法,返回一个原始值,则JavaScript返回这个值。 
3)如果无法从valueOf()和toString()获得一个原始值,此时就会抛出一个类型错误。

对象转换数字的细节解释了为什么空数组会被转换为数字0以及为什么具有单个元素的数组会被转换为一个数字。数组继承了默认的valueOf()方法,这个方法返回一个对象而不是一个原始值,因此数组到数字的转换调用toString()方法。空数组转换成空字符串,空字符串转换为数字0。含有一个元素的数组转换为字符串的结果和这个元素转换字符串的结果一样。如果数组只包含一个数字元素,这个数字转换为字符串,再转换为数字。 

JavaScript中的”+”运算符可以进行数学加法和字符串连接操作。如果它的其中一个操作是对象,则JavaScript将使用特殊的方法将对象转换为原始值,而不是使用其它算术运算符的方法执行对象到数字的转换。”==”相等运算符与此类似。如果将对象和一个原始值比较,则转换将会遵照对象到原始值得转换方式进行。 

“+”和“==”应用的对象到原始值得转换包含日期对象的一种特殊情形。日期类是JavaScript语言核心中唯一的预先定义类型,它定义了有意义的向字符串和数字类型的转换。对于所有非日期的对象来说,对象到原始值的转换基本上是对象到数字的转换(首先调用valueOf),日期对象则使用对象到字符串的转换模式。然而这里的转换(+ ==)和上文讲述的并不完全一致:通过valueOf和toString 返回的原始值将被直接使用,而不会被强制转换为数字或者字符串。

和“==”一样,“<”运算符以及其它关系算术运算符也会做到对象到原始值得转换,但要除去日期对象的特殊情形:任何对象都会先尝试调用valueOf,然后调用toString。不管得到的原始值是否直接使用,它都不会进一步被转换为数字或字符串。 

“+”、“==”、“!=”和关系运算符是唯一执行特殊的字符串到原始值的转换方式的运算符。其它运算符到特定类型的转换很明确,而且对日期对象来讲也没有特殊情况。例如“-”运算符把它的两个操作数都转换为数字。下面演示日期对象、“+”、“-”、“==”、“>”的结果:

var now=new Date();
console.log(typeof (now+1));//string +号把日期转换为字符串
console.log(typeof (now-1));//number -号把对象到数字的转换
console.log(now==now.toString());//true 
console.log(now>now-1);//true >把日期转换为数字

八、变量声明

当声明一个JavaScript全局变量时,实际上是定义了全局对象的一个属性。
当使用var声明一个变量时,创建的这个属性是不可配置的,也就是说这个变量无法通过delete运算符删除。如果没有使用严格模式并给一个未声明的变量赋值的话,JavaScript会自动创建一个全局变量,以这种方式创建的变量是全局对象的正常的可配置属性,并可以删除它们:

var a = 1;       //声明一个不可删除的全局变量
b = 2;           //创建全局对象的一个可删除的属性
this.c = 3;      //同上
delete a;        //false
delete b;        //true
delete this.c;   //true

文章参考来源:《JavaScript 权威指南》(原书第六版) 作者 弗兰纳根

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值