本节内容引用 《JavaScript 标准参考教程(alpha)》,by 阮一峰
一.null & undefined
- null:属于对象类型Object,表示一个对象为空,即是找不到该对象,JavaScrit会自动回收为null的变量,避免占用无效的空间,转为数值时为0.
- undefined:单独的一种类型undefined,表示“未定义”或不存在,即由于目前没有定义,所以此处暂时没有任何值.undefined是一个表示”无”的原始值,转为数值时为NaN。
示例:
// 变量声明了,但没有赋值
var i;
i // undefined
在if语句中,它们都会被自动转为false,相等运算符(==)中两者是相等的。
null === undefined;//false
null =- undefined ;//true
二.对象-引用类型
1.定义
- 对象是对一个事物的抽象描述,它是事物的许多特性的集合体,一切皆是对象。
- 对象(object)是JavaScript的核心概念,也是最重要的数据类型。JavaScript的所有数据都可以被视为对象。
2.组成
对象由多个键值对组成。
- 键名即是对象的属性(property),键名都是字符串类型,有无引号都可(但要为非法的标识符号加上引号方可识别)
- 属性的值可以是任何类型,属性与值之间用冒号隔开,多个属性间用逗号隔开。属性值也可以是一个函数,称为方法。
如:
var student = {
name = "jack",
age = 18,
height = 180
}
上述对象是一个叫jack的student,年龄18,身高180.
3.Object
JavaScript中的所有对象都继承自Object,即是Object是所有对象的父类,Object 对象中的所有属性和方法都会出现在其他对象中。
属性:
- constructor
对创建对象的函数的引用(指针)。对于 Object 对象,该指针指向原始的 Object() 函数。 - Prototype
对该对象的对象原型的引用。对于所有的对象,它默认返回 Object 对象的一个实例。
方法:
- hasOwnProperty(property)
判断对象是否有某个特定的属性。必须用字符串指定该属性。(例如,o.hasOwnProperty(“name”)) - IsPrototypeOf(object)
判断该对象是否为另一个对象的原型。 - PropertyIsEnumerable
判断给定的属性是否可以用 for…in 语句进行枚举。 - ToString()
返回对象的原始字符串表示。对于 Object 对象,ECMA-262 没有定义这个值,所以不同的 ECMAScript 实现具有不同的值。 - ValueOf()
返回最适合该对象的原始值。对于许多对象,该方法返回的值都与 ToString() 的返回值相同。
4.引用
如果不同的变量名指向同一个对象,那么它们都是这个对象的引用,也就是说指向同一个内存地址。修改其中一个变量,会影响到其他所有变量。
var o1 = {};
var o2 = o1;
o1.a = 1;
o2.a // 1
o2.b = 2;
o1.b // 2
上面代码中,o1和o2指向同一个对象,因此为其中任何一个变量添加属性,另一个变量都可以读写该属性。
此时,如果取消某一个变量对于原对象的引用,不会影响到另一个变量。
var o1 = {};
var o2 = o1;
o1 = 1;
o2 // {}
上面代码中,o1和o2指向同一个对象,然后o1的值重新赋值变为1,这时o2还是指向原来的那个对象。
但是,这种引用只局限于对象,对于原始类型的数据则是传值引用,也就是说,都是值的拷贝。
5.创建对象
方式一:直接定义属性与值
var student = {
name = "jack",
age = 18,
height = 180
};
方式二:利用父类Object来生成对象然后添加属性
var student = new Object();
student.name = "jack";
student.age = 18;
student.height = 180;
方式三:一般用在需要对象继承的场合
var student2= Object.create(Object.prototype);
备注
JavaScript允许属性的“后绑定”,即可在任意时刻新增属性,没必要在定义对象的时候,就定义好属性。
var student = {};
student.name = "jack";
student.age = 18;
6.操作属性
<1>.读取属性
方式一:使用点运算符
student.name;//jack
数值键名不能使用点运算符(会被当成小数点),只能使用方括号运算符。
方式二:使用方括号运算符。
student['age'];//18
如果使用方括号运算符,键名必须放在引号里面,否则会被当作变量处理。但是,数字键可以不加引号,因为会被当作字符串处理。
<2>.检查对象是否包含属性
方式一:in运算符
"name" in student;//true
"birth" in student;//false
它无法识别对象继承的属性,即继承的属性也会判断为true.
方式二:Object对象自带的方法hasOwnProperty
该方法只判断自身的属性为true,继承的属性为false.
student.hasOwnProperty("name");//true
student.hasOwnProperty("birth");//false
<3>.遍历属性
方式一:利用Object的方法keys
Object.keys(student);//["name","age","height"]
方式二:for…in循环
var arr = [];
var i = 0;
for (arr[i++] in student);
arr;//["name","age","height"]
它遍历的是对象所有可遍历(enumerable)的属性,会跳过不可遍历的属性
它不仅遍历对象自身的属性,还遍历继承的属性。
7.with语句
with语句的格式如下:
with (object) {
statements;
}
它的作用是操作同一个对象的多个属性时,提供一些书写的方便。
// 例一
with (o) {
p1 = 1;
p2 = 2;
}
// 等同于
o.p1 = 1;
o.p2 = 2;
注意,with区块内部的变量,必须是当前对象已经存在的属性,否则会创造一个当前作用域的全局变量。这是因为with区块没有改变作用域,它的内部依然是当前作用域。
var o = {};
with (o) {
x = "abc";
}
o.x // undefined
x // "abc"
上面代码中,对象o没有属性x,所以with区块内部对x的操作,等于创造了一个全局变量x。正确的写法应该是,先定义对象o的属性x,然后在with区块内操作它。
with语句的一个很大的弊病,就是绑定对象不明确。建议不要使用with语句,可以考虑用一个临时变量代替with。with语句少数有用场合之一,就是替换模板变量。