对象
学习对象之前,应该先对javaScript的数据类型有一个简单的了解
数据类型
javaScript的数据类型分为两类:第一类为基本类型;第二类为引用类型
基本类型
- Number (数字)
- String (字符串)
- Boolean (布尔值,true和false)
- null (空)
- undefined (未定义)
引用类型
- Object (对象)
对象又可以分为:
- Function (函数)
- Array(数组)
- Date(日期)
- Regexp(正则)
- ...等等
如果想更加直观的方便输出的是哪种类型,可以使用typeof进行检验:

1. 对象字面量
对象字面量提供了一种非常方便的创建新对象值的表示法。一个对象字面量就是包围在一对花括号中的零或者多个“名/值”对。对象字面量可以出现在任何允许表达式出现的地方
var empty_object = {} //空对象
var student = {
"name": "zhangsan",
"gender": "male"
}
属性名可以是包括空字符串在内的任何字符串。在对象字面量中,如果属性名是一个合法的JavaScript标识符且不是保留字,并不强制要求用引号括住属性名。所以用引号括住属性值"zhangsan"是必须的,但是否括住属性名"name"则是可选的。使用逗号用来分隔多个“名/值”对。
属性的值可以从包括另一个对象的字面量在内的任意表达式中获得。对象是可以嵌套的:
例如:person对象嵌套一个hobby对象
var person = {
name: "zhangsan",
age: 21,
hobby: {
eat: "cake",
play: "computer games"
}
}
2. 检索
要检索对象中包含的值,可以采用在[]后缀中括住一个字符串表达式的方式。如果字符串表达式是一个常数,而且是一个合法的JavaScript标识符而非保留字,也可以用属性名.属性名来表示,推荐使用属性名.属性值的方式。

例如:输出一个student对象不存在的age属性

var empty_object = {}
var student = {
name: "zhangsan",
gender: "male"
}
var age = student.age || "none"
console.log("输出:" + age)

var empty_object = {}
var student = {
name: "zhangsan",
gender: "male"
}
console.log(student.age)
console.log(student.age.model)

可以通过&&运算符来避免
console.log(student.age && student.age.model)
输出undefined,避免报错。

3. 更新
对象中的值可以通过赋值语句来更新。
- 如果属性名已经存在在于对象中,那么这个属性的值将被替换。


4. 引用
对象通过引用来传递。它们永远不会被拷贝
var student = {
"name": "zhangsan",
"gender": "male"
}
var studentCopy = student;
studentCopy.name = 'wangwu'
//因为studentCopy和student是指向同一个对象的引用,所以student的name也改变成wangwu了
console.log(student.name)
console.log(studentCopy.name)
console.log(student.name === studentCopy.name)
var a={},b={},c={}
//a、b和c每个都引用不用的空对象
a=b=c={}
//a、b和c都引用同一个空对象
输出结果为:

5. 原型
每个对象都连接到一个原型对象,并且可以从中继承属性。给Object增加一个beget方法,用于创建一个使用原对象作为原型的新对象。
//定义一个student作为原型对象
var student = {
name: "zhangsan",
gender: "male",
age: 18,
score: 80
}
if (typeof Object.beget != 'function') {
Object.beget = function(o) {
var F = function() {}
F.prototype = o
return new F()
}
}
//定义一个新对象,使用student为原型
var collegeStudent = Object.beget(student)
//更新新对象不会改变该对象的原型
collegeStudent.name = "zhaoliu";
console.log(student.name)
console.log(collegeStudent.name)
//新对象未定义的属性值继承原型的属性值
console.log("新对象:" + collegeStudent.gender)
原型连接在更新时是不起作用的,例如在对某个对象做出改变时,不会触及到该对象的原型;

原型关系是一种动态关系,如果在原型中添加一个新的属性,该属性马上会对基于该原型创建的对象可见。
//为原型添加一个birthday属性
student.birthday = "1998-04-07"
//新对象自动继承原型新添加的属性
console.log("collegeStudent.birthday:" + collegeStudent.birthday)
输出:

6. 反射
检查对象并确定对象有什么属性,可以试着去检索该属性并验证取到的值。 使用typeof操作符对确定属性的类型很有帮助:
var student = {
name: "zhangsan",
gender: "male",
age: 18,
score: 80
}
//输出student的属性类型
console.log("student的属性:" + typeof student.name)
console.log("student的属性:" + typeof student.gender)
console.log("student的属性:" + typeof student.age)
console.log("student的属性:" + typeof student.score)
//注意:原型链中的属性也会产生值,例如:
console.log("原型链的属性:" + typeof student.toString)
输出

typeof判断并剔除掉function,但是,这样做的话,所有的函数都会被剔除。
另一种方法是使用hasOwnProperty方法,如果对象拥有独有的属性,他将返回true。hasOwnProperty方法不会监查原型链。
//属于自己的
console.log(student.hasOwnProperty('name'))
//属于自己的
console.log(student.hasOwnProperty('age'))
//属于原型链的
console.log(student.hasOwnProperty('toString'))
输出

7. 枚举
- 使用for in语句可以用来遍历一个对象的所有属性名(包括函数),可以使用typeof来排除函数
var student = {
name: "zhangsan",
gender: "male",
age: 18
}
for (name in student) {
if (typeof student[name] !== 'function')
console.log(name + ':' + student[name])
}

var properties = [
'age',
'name'
]
for (var i = 0; i < properties.length; i++) {
console.log(properties[i] + ":" + student[properties[i]])
}

var student = {
name: "zhangsan",
gender: "male",
age: 18
}
console.log(Object.keys(student));

8. 删除
delete运算可以用来删除对象的属性,它将一处对象中确定包含的属性。
var student = {
name: "zhangsan",
gender: "male",
age: 18,
score: 80
}
//删除自己的属性
console.log("删除前")
console.log(student)
delete student.name
console.log("删除后")
console.log(student)

但是delete删除不会触及原型链中的任何对象。如:
var student = {
name: "zhangsan",
gender: "male",
age: 18,
}
if (typeof Object.beget != 'function') {
Object.beget = function(o) {
var F = function() {}
F.prototype = o
return new F()
}
}
//定义新的collegeStudent对象,使用student对象为原型
var collegeStudent = Object.beget(student)
console.log("删除前" + collegeStudent.name)
//collegeStudent尝试删除原型的属性
delete collegeStudent.name;
console.log("删除后" + collegeStudent.name)
</script>

9. 减少全局变量污染
JavaScript可以随意的定义全局变量,但是,全局变量降低了程序的灵活性,应该避免这个问题。 最小化的使用全局变量的方法就是在应用中只创建唯一一个全局变量:
var CONTAINER = {}
这时可以将这个变量当成应用的容器;
var CONTAINER = {}
CONTAINER.student = {
"name": "zhangsan",
"gender": "male"
}
CONTAINER.person = {
name: "",
age: 21,
hobby: {
eat: "cake",
play: "computer games"
}
}
这要把多个全局变量定义在一个名称空间下,就可以显著降低与其他程序、组件或类库中间互相影响的可能性,程序的可读性也更好。