前言
JavaScript是面向Web的编程语言。绝大多数网站都是用了JavaScript,并且所有现在的Web浏览器-基于桌面系统、游戏机、平板电脑和智能手机的浏览器均包含了JavaScript解释器。这使得JavaScript的使用范围非常广。
如果y你有其他编程语言基础,这有助于你了解JavaScript这门高级的、动态的、弱类型语言。JavaScript非常适合面向对象和函数式的编程风格。JavaScript的语法源自Java,它的一等函数来自于Scheme,它的基于原型的继承来自于Self。
基础
JavaScript中除了number、string、boolean、null、undefined之外都是对象。
JavaScript中有一种特殊的对象-全局对象。
JavaScript中只有对象才能拥有方法。只有null和undefined是无法拥有方法的。number、string、boolean虽然不是对象但是也可以拥有方法,这是因为当我们在他们(string、number、boolean)身上调用方法时,JavaScript会帮我们临时生成一个(String、Number、Boolean)对象。
JavaScript的类型可以分为原始类型和对象类型。也可以分为对象类型和基本类型。同样可以分为可变类型和不可变类型。对象和数组属于可变类型,数字、布尔、null、undefined属于不可变类型。
JavaScript不区分整数值和浮点数值。JavaScript中的所有数字军用浮点数值标识。
null和undefined
null
null是JavaScript语言的关键字,用来表示空值。对null执行typeof操作,结果返回object。也就是说,可以把null理解成一个特殊的对象值,含义是“非对象”。但事实上,通常认为null是他自有类型的唯一一个成员,null用来标识数字、字符串和对象是“无值”的。JavaScript中的null和其他编程语言中的null以及nil很相似。
undefined
undefined是JavaScript中另一个用来表示空值的变量。注意undefined是预定义的全局变量,undefined和null不一样,他不是关键字。undefined的值就是“undefined”。undefined通常用于表示更深层次的“空值”。他是变量的一种取值,表明变量没有初始化。如果要查询的对象属性或者数组元素的值不存在,则会返回undefined。如果函数没有返回任何值,则返回undefined。引用没有提供实参的函数形参的值也会得到undefined
。在ES3中,undefined是可读可写的变量,可以给他赋任意值。这个错误在ES5中被修正了,undefined在ES5中只读。如果用typeof运算符得到undefined的类型,则返回“undefined”。表明undefined这个值是这个类型的唯一成员。
null和undefined的异同
尽管null和undefined是不同的,但他们都表示“值的空缺”。两者往往可以互换。“==”运算符认为两者相等。“===”认为他俩不相等。所以要区分null和undefined需要使用“===”运算符。null和undefined都不包含任何属性和方法,所以把他们当成对象来使用都会产生一个类型错误。即使用“.”和“[]”来取这两个值的属性或方法都会产生一个类型错误
.
如果想使用“空值”初始化一个变量或对象,请使用null,而非undefined。undefined是表示系统级的、出乎意料的或类似错误的值的空缺,而null表示程序级的、正常的或在意料之内的指的空缺。
全局对象
JavaScript中有一类特殊的对象-全局对象。全局对象(global object)在JavaScript中有重要用途:全局对象的属性是全局定义的符号,JavaScript程序可以直接使用。当JavaScript解释器启动时或任何Web浏览器加载新页面的时候,他将创建一个新的全局对象,并给他一组定义好的初始属性:
- 全局属性,比如 undefined、Infinity、NaN(not a number)
- 全局函数,r比如 isNaN()、parseInt()
- 构造函数, 比如 Date()、RegExp()、String()、Object()、Array()
- 全局对象,比如 Math和Json
PS
:全局对象的初始属性并不是保留字,但他们应该被当成保留字来对待。
如下图,是JavaScript中预定义的全局变量和函数。
在代码的最外层(不在任何函数内的JavaScript代码),可以使用JavaScript关键字this获得全局对象的引用(即在最外层,this引用着全局对象):
1 | var global = this; // 定义一个全局变量"global"来引用全局对象 |
在客户端JavaScript中,Window对充当了全局对象。这个全局对象有一个名为window的属性引用了全局对象自身,全局对象的window属性可以代替this来引用全局对象。Window对象定义了核心的全局属性,但他也针对于Web浏览器和客户端JavaScript定义了一少部分其他的全局属性。
JavaScript中,全局对象定义了JavaScript中所有的预定义全局值。同样,全局对象也包含了(程序员)为程序定义的(程序级别的)全局变量。也就是说,在JavaScript中,如果代码声明了一个全局变量,那么这个全局变量就是全局对象的一个属性。
包装对象
什么是包装对象
包装对象是指将基本数据类型包装成对应的对象类型的对象。例如number的包装对象是Number,string的包装对象是String,boolean的包装对象是Boolean。
我们知道,所有面向对象的语言中,只有对象才拥有属性和方法。通常,我们可以通过“.”运算符来调用对象的属性,也可以通过“.”运算符来调用对象的方法。但是字符串(string)作为JavaScript的基本数据类型(string并不是对象类型)为什么h它会有属性和方法呢?如下,JavaScript中,调用字符串的属性和方法将会正常运行,并不会抛出任何错误:
1 | var str = "hello world" |
原因:只要调用了字符串str的属性或者方法,JavaScript就会将字符串通过调用new String(str)的方式转换成String对象。这个对象继承了字符串的方法和属性。并被用来处理方法和属性的引用(即方法或属性的调用者),一旦处理完毕,这个临时床架的新对象就会被销毁。
同字符串一样,数字和布尔也具有格子的方法。通过Number()和Boolean()构造函数创建一个临时对象,这些方法的调用均来自于这个临时对象。
PS
:null和undefined没有包装对象,所以在null或undefined身上访问属性或方法会造成一个类型错误。
不要试图给number、string、boolean的属性或方法赋值
看如下代码,思考执行结果:
1 | var s = "test" // 创建一个原始字符串 |
当运行这段代码时,length的值是undefined。因为:第二行代码创建了一个临时字符串对象,并给这个临时字符串对象添加了一个名为count的属性,然后给count属性赋值为4,随后第二行代码执行完成,临时字符串对象立即被销毁。第三行依旧是读取的原始字符串s的count属性,我们知道,原始字符串并不是对象,他没有任何属性和方法,count这个属性自然不存在,所以结果是undefined。这段代码说明:在读取number、string、boolean的属性或方法时,其行为表现的像对象一样,但如果视图给number、string、boolean的属性赋值,则会忽略这一操作,因为修改只是发生在临时对象身上,而临时对象并没有被保存下来。
显示创建包装对象
可以通过String()、Number()、Boolean()构造函数显示的创建包装对象。JavaScript会在必要的时候将包装对象转换为原始值。下面代码中,包装对象S、N、B常常表现的和s、n、b一样。“==”运算符j将原始值和包装对象认为相等(JavaScript会将包装对象转换为原始值),“===”则认为他们不相等。通过typeof运算符可以看到原始值和包装对象的不同。
1 | var s = "test" |
总结:调用string、number、boolean的属性或方法时临时创建的对象称为包装对象,它只是偶尔用来区分字符串值和字符串对象、数字和数字对象、布尔值和布尔对象。通常,包装对象的创建和销毁是JavaScript自动管理的,包装对象只是被看做是一种实现细节,我们只需要知道在调用某个字符串或数字的属性或方法时,JavaScript为我们做了什么,而不用特别关注。
敬请期待~