对象
拥有方法和属性的一个集合可称为对象,对象的方法和属性可以改变。
对象的类型
根据上述的定义可知,只有引用类型的变量也就是复杂类型的变量才满足作为对象的条件, 所以比较常见的对象包括函数、数组等等,当然不要忘了对象也是对象。
对象的字面量
比较方便的创造新对象的一种表示方法
var person = {
name : "xiaojiang",
age : 20
}
这就简单的创建了一个名为person的对象,该对象有两个属性:name 和 age,当然由于属性名是字符串,也可用分号括起来
var person = {
"name" : "xiaojiang",
"age" : 20
}
这个代码的运行结果与上式相同
对象属性的值可以是另一对象字面量,对象是可嵌套的
var flight = {
// 创建一个航班对象对象
airline : 'SYD',
number : 815 ,
departure : {
IATA : 'SYD',
time : '2004-09-22 14:55',
city : 'Sydney'
},
arrival : {
IATA : 'LAX',
time : '2004-09-23 10:42',
city : 'Los Angeles'
}
}
检索与更新
可采用[]括住字符串表达式或者.表示法实现检索 当尝试检索一个对象不存在的值会返回undefined。 对象里属性的值可以用赋值语句更新,如果对象值之前没有拥有那个属性名,那么该属性就会被扩充到对象里
flight.flytime = "20hours"
console.log(flight.flytime) //20hours
当对象里嵌着对象时,检索需用两层实现
var objt = {a:{b:10}}
console.log(objt.a.b)
console.log(objt["a"]["b"])
引用
对象的引用其实就是对象的复制,但是对象本身不能被赋值语句直接复制,如直接使用赋值语句复制,那么复制的其实只是指向对象的指针,当两个指针同时指向一个对象时,其中一方的指针对对象做了更新,那么你用另一方指针检索该对象被更新的属性时显示的结果也是更新后的结果.
var objt = {a:10}
var o = objt
objt.a = 20
console.log(o.a)// 输出值为20
既然普通的赋值语句只是对指向对象的指针进行复制,那么如何实现对对象本身的拷贝呢 而这里又分为浅拷贝和深拷贝。
浅拷贝
当对象的属性里不包含对象时,可以通过for in来遍历对象的属性进行浅拷贝
var objt = {a:10}
function shallowCopy(objt){
var newobjt = {}
for (var attr in objt){
newobjt[attr] = objt[attr]
}
return newobjt
}
var newobjt = shallowCopy(objt)
objt.a = 20
console.log(newobjt.a)// 输出值为10
深拷贝
上述代码中实现拷贝的语句为 newobjt[attr] =objt[attr] 若传进来的attr(属性)的值为另一个对象时,那么此时语句执行的结果也就是一个仅仅的赋值语句,拷贝的也仅仅是一个指向对象的指针,可见用上述代码解决不了嵌套对象的拷贝,而对嵌套对象的拷贝,我们也称它为深拷贝,实现深拷贝的主要方法是递归。
var obj = {a:{b:10}}
function deepCopy(obj){
if(typeof obj != 'object'){
return obj
}
var newobj = {}
for(var attr in obj){
newobj[attr] = deepCopy(obj[attr])
}
ruturn newobj
}
var newobj = deepCopy(obj)
原型
原型是每个对象都有的属性,原型也是一个对象。 由于对象可以访问其原型的属性,所以当你想用某个对象的属性时,可将当前的对象的原型设为该对象,你就拥有了该对象的使用权。而如果对象在创建没有自定义设置该对象的原型,那么该对象的原型就是Object{} -proto-属性是对象的隐形属性,其值就是指向对象的原型对象,es5自定义对象的原型的方式就是通过-proto-设置
es6设置原型的方式
var a = {a:10}
var b = {b:3}
Object.setPrototypeOf(a,b)//将b设置为a的原型
console.log(a.b)// 输出值为3
提到原型不得不提到构造函数,对象的创建除了用对象字面量创建,还能用构造函数创建
function A(name,age){
this.name = 'xiaohong'
this.age = 14
}
var person = new A()
以上的构造函数A里面有一个属性叫prototype,当通过用构造函数创建实例对象时,会将构造函数的prototype属性赋值给person实例对象的原型,也是就person这个实例对象的原型会指向构造函数的prototype属性
A.prototype.hobby = function(){
return 'play basketball'
}
console.log(person.hobby())//play basketball
以上通过调用构造函数的prototype给实例对象调用函数; constructor属性是原型对象的一个属性,作用是能返回以该原型对象为原型对象的对象的构造函数,简而言之就是找到一个对象的构造函数,可以通过访问该对象的原型对象的constructor属性,因为继承关系即可直接访问该对象的constructor属性来找到其构造函数
console.log(person.constructor) //Function A
反射和枚举
反射机制指一个程序在运行知道自身有哪些信息,比如一个对象在运行时知道自己有哪些方法和属性 用tpyeof来判断属性的类型
typeof flight.number //'number'
typeof flight.arrival //'object'
用for in来实现枚举,但是用for in会导致属性出现的顺序是不确定的
删除
用delete运算符来删除对象的属性,并且它不会触及原型链中的任何对象,但是有一点,删除对象的属性可能会让来自原型链中的属性透视出来
减少全局变量的污染
可使用的方法是可只创建一个唯一的全局变量,然后把所有全局性的资源都放入其中,还有闭包。