var person = new Object();
person.name = ‘豪情’;
person.age = 29;
person.sayName = function(){
alert(this.name);
}
抽象了创建具体对象的过程,用函数来封装以特定接口创建对象的细节
function createPerson(name, age, job){
var o = new object();
o.name = ‘豪情’;
o.age = age;
o.job = job;
o.sayName = function(){
alert(this.name);
}
return o;
}
var person1 = createPerson(‘豪情’, 29, ‘打杂’);
person1.sayName(); // output 豪情
解决了创建多个相似对象的问题,但没有解决对象类型识别问题
function Person(name, age){
this.name = name;
this.age = age;
this.sayName = function(){
alert(this.name);
}
}
var person1 = new Person(‘豪情’, 29);
person.sayName() //output 豪情
构造函数模式的缺点:在全局作用域中定义的函数实际上只能被某个对象引用,如果对象定义很多方法,那么就要定义很多个全局函数,我们定义的这个引用类型没有封装性可言。
我们创建的每个函数都有一个prototype(原型)属性,这个属性是一个对象,它的用途是包含可以由特定类型的所有实例共享的属性和方法。换句话说,prototype就是通过调用构造函数而创建的那个对象的原型对象。使用它的好处是可以让所有的对象实例共享它所包含的属性和方法。
function Person(){}
Person.prototype.name = ‘豪情’;
Person.prototype.age = 29;
Person.prorotype.sayName = function(){
alert(this.name);
}
var person1 = new Person();
person1.sayName(); // output 豪情
1. 理解原型
无论什么时候,只要创建了一个新函数,就会根据一组特定的规则为该函数创建一个prototype属性。在默认的情况下,所有prototype属性都会自动获得一个constructor属性,这个属性包含一个指向prototype属性函数的指针。
2. 原型与in操作符
两种使用in操作符的场合:单独使用或for-in循环中
单独使用:in操作符会在通过对象能够访问给定属性时返回true
3. 更简单的原型语法
function Person(){}
Person.prototype = {
name: ‘豪情’,
age: 29,
sayName: function(){
alert(this.name);
}
}
4. 原型的动态性
重写原型会切断现有原型与任何之前已经存在的对象实例之间的联系,虽然它们引用的仍然是最初的原型
5. 原生对象的原型
可以扩展原生对象的方法
String.prototype.startWith = function(){
return this.indexOf(text) == 0;
}
var msg = ‘hello world’;
alert(msg.startWith(‘hello’)); //output true
6. 原型对象的问题
原型中所有属性被很多的实例共享,对于包含引用类型的属性来说,就不怎么乐观。
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);
}
}
}
这种模式的基本思想是创建一个函数,该函数的作用是封装创建对象的代码,然后再返回新创建的对象
没有公共属性,而且其方法不引用this的对象
许多OO语言都支持:接口继承和实现继承。接口继承只继承方法签名,而实现继承则继承实际的方法。由于函数没有签名,在JavaScript中无法实现接口继承。只支持实现继承。主要靠原型链来实现继承。
原型链实现继承的原理:利用原型让一个引用类型继承另一个引用类型的属性和方法。回顾一个构造函数、原型和实例的关系:每个构造函数都有一个原型对象,原型对象都包含一个指向构造函数的指针,而实例都包含一个指向原型对象的内部指针。那么假如我们让原型对象等于另一个类型的实现,结果会怎么样呢?显然,此时的原型对象将包含一个指向另一个原型的指针,相应地,另一个原型中也包含着一个指向另一个构造函数的指针。假如另一个原型又是另一个类型的实例,那么上述关系成立。如此层层递进,就构成了实例与原型的链条。
function Super(){
this.colors = [‘red’, ‘blue’, ‘green’];
}
function Sub(){
Super.call(this);
}
有的时候叫伪经典继承。指的是原型链和借用构造函数的技术组合到一块,从而发挥二者之长的一种继承模式。其思路是使用原型链实现对原型属性和方法的继承,而通过借用构造函数来实现对实例属性的继承。
借助原型可以基于已有的对象创建新对象,同时还不必因此创建自定义类型。
function object(o){
function F(){};
F.prototype = o;
return new F();
}
即创建一个仅用于封装继承过程的函数,该函数在内部以某种方式来增强对象,最后再像真地是它做了所有工作一样返回对象。
function createAnother(original){
var clone = object(original);
clone.sayHi = function(){
alert(‘hi’);
};
return clone;
}
function SuperType(name){
this.name = name;
this.colors = [‘red’, ‘blue’, ‘green’];
}
SuperType.prototype.sayName = function(){
alert(this.name);
}
function SubType(name, age){
SuperType.call(this, name);
this.age = age;
}
SubType.prototype = new SuperType();
SubType.prototype.sayAge = function(){
alert(this.age);
}