在写之前,突然想到了一句话:程序员也要有程序员的高风亮节和骨气,不拿来主义,不做伸手党,最没节操的就是拿来之后直接压箱底儿了。
闲言少叙,正题。
一、对象是什么?为什么要面向它?
对象,说白了就是键值对的一个集合,而其中的值又可以是数据或者函数而已。面向对象,实际是一种程序设计的方式。上古时代的编程一般都是面向过程式的,想到一行写一行,除了if else 就是 无穷的一个接一个的函数。而为了让程序不再如同一盘散沙,而是有机的组合在一起(方便维护,方便扩展),那么面向对象(Object-Oriented,OO)就粉末登场啦。
二、对象的属性分类及高级功能
属性分类:数据属性 访问器属性
操作函数:
a Object.defineProperty (所属对象,属性名,描述符对象 ) 配置单个数据属性或访问器属性
b Object.defineProperties (所属对象,属性名 ) 配置多个数据属性和访问器属性
c Object.getOwnPropertyDescriptor(所属对象,要读取描述符对象的属性名) 读取属性的描述符对象(特性值:双方括号里的选项的值)
(一)数据属性:就是对象属性的一些可配置的性质的选项。
特点:包含数据值; 有 [[ Configurable ]]、 [[ Enumerable ]]、[[ Writable ]]、[[ value ]] 直接添加属性和方法的对象 ,选项值为true; 反之 选项值为false;
var person = {
name:"vin",
age:21,
say:function () {
alert(this.age);
}
}
// person.say();
Object.defineProperty(person,"name",{
configurable:false,
writable:false,
value:"zhangsan"
})
alert(person.name); // zhangsan
注意:可以多次调用Object.defineProperty 来对同一属性进行修改,但在把configurable 设置为false 后 无法再设置回可配置的了。
IE8 对于这个函数的实现不彻底,不推荐在ie8下使用该函数。
(二)访问器属性:
特点:不包含数据值;有 [[ Configurable ]]、 [[ Enumerable ]]、[[ get]]、[[ set]] 后两项默认为undefined
var book = {
_year:2004,
version:1
}
Object.defineProperty(book,"year",{
get:function () {
return this._year;
},
set:function (v) {
if(v > 2004) {
this._year = v;
this.version += v - 2004;
}
}
})
book.year = 2005;
alert(book.version); // 2
注意:在设置多个数据属性和访问器属性的时候,由于构建对象属性的方式非直接添加,因此 数据属性和部分访问器属性的配置项(书上叫特性值:双方括号里的那些东西)默认是false,在set属性的时候,需手动配置数据属性特性值为true
如:
// 定义多个属性
var book = {};
Object.defineProperties(book, {
// 数据属性
_year:{
value:2004,
},
version: {
value:1,
writable:true //手动设置可写 否则默认为false
},
// year 访问器属性 其中改变一个属性,另一个属性也将发生变化
year: {
get:function () {
return this._year;
},
set:function (v) {
if(v > 2004) {
this._year = v;
this.version += v-2004;
// alert("fuck");
}
}
}
})
book.year = 2006;
alert(book.version);
三、创建对象的方式:
设计模式:工厂模式、构造函数模式、原型模式、构造函数和原型混合模式、动态原型模式、寄生构造函数模式、稳妥构造函数模式。
1.工厂模式:
优点:解决了创建多个相似对象的问题 。
缺点:无法得知所创对象的类型。
典型实现方式: 函数+Object+return
function createPerson(name,age,job) {
var o = new Object();
o.name = name;
o.age = age;
o.job = job;
o.say = function () {
alert(this.name);
}
return o;
}
var zhangsan = createPerson("zhangsan",21,"cleaner");
var lisi = createPerson("lisi",26,"teacher");
zhangsan.say();//zhangsan
lisi.say(); //lisi
2. 构造函数模式:
优点:可以为对象实例标识为一种特定的类型,好过工厂模式
缺点:同一个方法要被实例化多次,方法(函数)被重复声明,浪费内存,没必要如此
典型实现方式: this + new
function Person(name,age,job) {
this.name = name;
this.age = age;
this.job = job;
this.say = function () {
}var wangwu = new Person("wangwu",23,"holer");var zhaoliu = new Person("zhaoliu",23,"holer");wangwu.say(); // wangwuzhaoliu.say();//zhaoliualert(this.name); }
function Person(name,age,job) { this.name = name; this.age = age; this.job = job; this.say = function () {
}var wangwu = new Person("wangwu",23,"holer");var zhaoliu = new Person("zhaoliu",23,"holer");wangwu.say(); // wangwuzhaoliu.say();//zhaoliualert(this.name); }
3. 原型模式
优点:将对象的属性和方法 通过prototype指针共享化,避免 构造函数的缺点
缺点:通过prototype共享引用类型的属性,出现张三的名字也是李四的名字悖论。
典型实现方式:空函数 + prototype
function Person() {}; Person.prototype.name = "vin"; Person.prototype.age = 21; Person.prototype.job = "cleaner"; Person.prototype.say = function () { alert(this.name); } var a = new Person(); a.say();// vin
---------------------------------------待续
function Person(name,age,job) { this.name = name; this.age = age; this.job = job; this.say = function () {
}var wangwu = new Person("wangwu",23,"holer");var zhaoliu = new Person("zhaoliu",23,"holer");wangwu.say(); // wangwuzhaoliu.say();//zhaoliualert(this.name); }