Javascript是使用克隆的原型模式。
1. 原型编程的规则
- 所有的数据都是对象(javascript中不是所有数据都是对象,如:undefined)
- 要得到一个对象,不是通过类实例化,而是找到一个对象最为原型并克隆他。
- 对象会记住他的原型。
- 如果对象无法响应某个请求,它会把这个请求委托给他的原型。
javascript的根对象是Object.prototype对象,Object.prototype对象是null。ECMAScript中提供了Object.getPrototypeof(obj) 来获取对象的原型。
2. 创建对象
Javascript中通过克隆创建对象,最初都是由Object.prototype对象克隆而来。比如我们创建一个var obj ={}的obj对象。这个obj对象就是由Object.prototype对象克隆而来。
- 在javascript中通过Object.create(obj)来克隆创建对象。
function A(name){
this.name = name
}
var a = new A('Patric');
console.log(a.name); // Patrick;
var b = Object.create(a);
b.name = 'Alice';
console.log(b.name); // Alice;
- 有些浏览器不支持Object.create(obj);可以用如下方法重写Object.create方法:
Object.create = Object.create || function(obj){
var F = function(){};
F.prototype = obj; // 把F对象的原型指向obj;
return new F();
}
上面所说对象是通过克隆创建的,那有时候我们会'实例'化一个函数,创建一个对象。如:
function Animal(content){
this.content = content;
this.say = function(){
console.log( this.content);
}
}
var dog = new Animal('汪汪');
dog.say(); //'汪汪';
这里的Animal并不是类,而是构造器函数,当通过new调用函数时,这个函数是一个构造函数。那么new是怎么工作的呢? 下面代码展示了new的工作过程。
function testFactory(){
var obj = new Object(); //从Object.prototype上克隆出一个对象;obj的原型是Object.prototype。
var Cons = [].shift.call(arguments);
obj['__proto__'] == Cons.prototype; //吧obj的原型指向传进来的对象的构造器上的prototype.
var ret = Cons.apply(obj,arguments);
return typeof ret == 'object'? ret: obj;
}
var dog = testFactory(Animal,"汪汪");
dog.say();// 汪汪
3. 原型与原型链
我们知道Javascript是克隆的原型模式。当通过Object.prototype创建一个对象A,A的原型就是Object.prototype. 又通过A创建一个B对象,B的原型指向A;这时就形成了一个原型链。每个对象都会记住他们的原型。当我们使用对象的属性或者方法时,会沿着这条原型链去查找,那么它什么时候停下来呢?当查找到Object.prototype的时候,Object.prototype是一个空对象,那么这个时候就会停止。
- 对象怎么记住原型?
对象的原型保存在对象的构造器里的prototype上,与其说对象把请求委托给对象的原型,还不如说是委托给了对象的构造器的原型。那么对象怎么把请求交给构造器的的原型呢? 通过_proto_。看下面的代码。
function A(){}
var a = new A();
console.log(Object.getPrototypeOf(a) === A.prototype); //true
console.log(a.__proto__ === A.prototype); // true.
对象通过_proto_ 指向对象构造器的原型;使得对象顺利的把请求交给它的构造原型。
以上内容是对《Javascript设计模式与开发实践》原型模式的简单总结与记录。
网友评论