面向对象的程序设计
创建对象
构造函数创建对象
var person=new Object(); person.name="Nicholas"; person.age=25; person.job="software engineer"; person.sayName()=function(){ alert(this.name); };
对象字面量创建对象
var person={ name:"Nicholas", age:25, job:"software engineer", asyName:function(){ alert(this.name); } };
属性类型
数据属性——包含一个数据值的位置,在这个位置可以读取和写入值
特性——[[Configurable]]、[[Enumerable]]、[[Writable]]、[[Value]]
-Object.defineProperty()方法——修改属性默认的特性
var person={}; Object.defineProperty(person,"name",{ configurable:false, value:"Nicholas" }); alert(person.name);
访问器属性
特性——[[Configurable]]、[[Enumerable]]、[[Get]]、[[Set]]
var book={ _year:2004, edition:1 }; Object.defineProperty(book,"year",{ get:function(){ return this._year; }, set:function(newValue){ if(newValue>2004){ this._year=newValue; this.edition+=newValue-2004; } } }); book.year=2005; alert(book.ediotn); //2
定义多个属性——Object.defineProperties()
读取属性的特性——Object.getOwnPropertyDescriptor()
var book={}; Object.defineProperties(book,{ _year:{ writable:true, value:2004 }, edition:{ writable:true, value:1 }, year:{ get:function(){ return this._year; }, set:function(newValue){ if(newValue>2004){ this._year=newValue; this.edition+=newValue-2004; } } } });
}); var descriptor=Object.getOwnPropertyDescriptor(book,"_year"); alert(descriptor.value); alert(descriptor.configurable);
工厂模式——用函数封装以特定接口创建对象的细节
function createPerson(name,age,job){ //函数封装 var o=new Object(); //创建对象 o.name=name; //添加属性和方法 o.age=age; o.job=job; o.sayName=function(){ alert(this.name); }; return o; } var person1=createPerson("Nicholas",29,"software engineer"); var person2=createPerson("Greg",27,"Doctor");
缺陷:无法识别对象的类型
构造函数模式
例一
function Person(name,age,job){ //自定义构造函数 this.name=name; //自定义对象类型的属性与方法 this.age=age; this.job=job; this.sayName=function(){ alert(this.name); }; } var person1=new Person("Nicholas",29,"software engineer"); var person2=new Person("Greg",27,"Doctor");
缺陷:方法sayName()要在每个实例中重新创建一遍
例二:将函数定义转移到构造函数外部
var person1=new Person("Nicholas",29,"software engineer"); var person2=new Person("Greg",27,"Doctor"); function Person(name,age,job) { this.name = name; this.age = age; this.job = job; this.sayName = sayName; } function(){ alert(this.name); }; var person1=new Person("Nicholas",29,"software engineer"); var person2=new Person("Greg",27,"Doctor");
缺陷:如果对象需要定义很多方法,那么就需要定义很多个全局函数
原型模式
-prototype(原型)——这个属性是一个指针,指向一个对象,这个对象的用途是包含可以由特定类型的所有实例共享的属性和方法
function Person(){ Person.prototype.name="Nicholas"; Person.prototype.age=29; Person.prototype.job="software engineer"; Person.prototype.sayName=function(){ alert(this.name); }; } var person1=new Person(); person1.sayName(); var person2=new Person(); person2.sayName();
方法isPrototypeOf()
方法Object.getPrototypeOf()
方法hasOwnProperty
方法Object.keys()
更简单的原型语法
function Person(){} Person.prototype={ constructor:Person, name:"Nicholas", age:29, job:"software engineer", friends:["shellby","Court"], sayName:function(){ alert(this.name); } }; var person1=new Person(); var person2=new Person(); person1.push("van"); alert(person1.friends); alert(person2.friends);
缺陷:属性与方法均共享,所有实例共享一个数组
组合使用构造函数模式和原型模式
构造函数模式——用于定义实例属性
原型模式——用于定义方法和共享的属性
function Person(name,age,job){ this.name=name; this.age=age; this.job=job; this.friends=["Shelby","Court"]; } Person.prototype={ constructor:Person, sayName:function(){ alert(this.name); } } var person1=new Person("Nicholas",29,"software engineer"); var person2=new Person("Greg",27,"Doctor");
动态原型模式
构造函数——封装所有的信息(属性与方法)
构造函数——初始化原型(仅在必要情况下)
function Person(name,age,job) {
this.name = name;
this.age = age;
this.job = job;
if (typeOf this.sayName != "function")
{
Person.prototype.sayName = function () {
alert(this.name);
};
}
}
var person1=new Person("Nicholas",29,"software engineer");
person1.sayName();