学习了js对象一节,细节挺多,特此总结一下:
1.对象属性遍历,for in。或者Object.keys(obj), Object.getOwnPropertyNames(obj),这两个都可以获得实例对象的属性,但是prototype中定义的属性无法获取。可以通过Class.prototype 作为参数的方式来访问。
如下:
function Person(name, job){
this.name = name;
this.job = job;
/*
每次创建一个对象,都会创建一个新的该方法,即: o1.sayName != o2.sayName //true
可以创建全局方法避免,但是创建无谓的全局方法总是不太好的。
所以,用原型链 可以解决该问题。
*/
this.sayName = function(){
console.log( this.name );
}
}
Person.prototype.age = 33;
var p1 = new Person('zhouyong', 'software enginer');
console.log( Object.keys(p1) ); //["name", "job", "sayName"]
console.log( Object.getOwnPropertyNames( p1 ) ); //["name", "job", "sayName"]
console.log( Object.keys( Person.prototype ) ); //["age"]
console.log( Object.getOwnPropertyNames( Person.prototype ) ) //["constructor", "age"]
for(var prop in p1){
console.log( prop );
}
/*
name
job
sayName
age
*/
此外,每一个类都继承了hasOwnProperty()方法。
Person.hasOwnProperty('name'); //true
2.定义对象的几种方法
1)构造函数模式
function Person(name, job){
this.name = name;
this.job = job;
this.sayName = function(){
console.log( this.name );
}
}
缺点:每次new一个对象的时候,里面的sayName都会重新生成一个Function实例。可以把function放在外面,但是又会影响外面的全局变量。
2) 原型模式
function Person(){
}
Person.prototype.name = 'zhouyong';
Person.prototype.age = 33;
Person.prototype.job = 'Software Engineer';
Person.prototype.hobby = ['football', 'swing'];// 注意:这里是一个 对象,而不是基本的数据类型
缺点:
如上所示,如果new两个对象p1和p2,则p1和p2的hobby属性指向同一个地址,是共享的。当改变p1的hobby改变时,会影响p2。
3)构造函数模式和原型模式组合使用。
这是最常用的方式,属性用构造函数模式,方法用原型模式,这样组合使用,避免缺点。