原型模式&原型继承

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/HCJS_Zee/article/details/83004602

使用克隆的原型模式

从设计模式角度讲,原型模式是用于创建对象的一种模式,如果我们要创建一个对象,一种方法是先指定它的类型,然后通过类来创建这个对象。原型模式选择了另外一种方式,不用关心对象的具体类型,而是通过克隆来创建一个一模一样的对象。

原型模式的实现关键,是语言本身是否提供了clone方法。ECMAScript5提供了Object.create方法,可以用来克隆对象。

var Plane = function(){
	this.blood = 100;
	this.attackLevel = 1;
	this.defenseLevel = 1;
}
var plane = new Plane();
plane.blood = 500;
plane.attackLevel = 10;
plane.defenseLevel = 7;
var clonePlane = Object.create(plane);
console.log(clonePlane); //输出:Object{blood: 500, attackLevel: 10, defenseLevel: 7}

//在不支持Object.create 方法的浏览器中,则可以使用以下代码:
Object.create = Object.create || function(obj) {
	var F = function(){};
	F.prototype = obj;
	return new F();
}

JavaScript中的原型继承

1、所有的对象都是从Object.prototype对象克隆而来。

var obj1 = new Object();
var obj2 = {};
Object.getPrototypeOf(obj1) === Object.prototype;// true
Object.getPrototypeOf(obj2) === Object.prototype;// true

2、要得到一个对象,不是通过实例化类,而是找到一个对象作为原型并克隆它。

在JavaScript里,我们不需要关心克隆的细节,由内部引擎负责实现。我们显示地调用var obj1 = new Object()或者var obj2 = {}。此时引擎内部会从Object.prototype上面克隆一个对象出来,我们最终得到的就是这个对象。

使用new操作符从构造器中得到一个对象

function Person(name){
	this.name = name;
};
Person.prototype.getName = function(){
	return this.name;
};
var a = new Person('zee');
console.log(a.name);//zee
console.log(a.getName());//zee
console.log(Object.getProttotypeOf(a) === Person.prototype);//true

用new运算符来创建对象的过程,实际上也只是先克隆Object.prototype对象。

new运算的过程:

function Person(name){
	this.name = name;
};
Person.prototype.getName = function(){
	return this.name;
};
var objectFactory = function(){
	var obj = new Object(), // 从Object.protoype上克隆一个空的对象
		Constructor = [].shift.call(arguments);//取得外部传入的构造器,此例是Person
		obj.__proto__ = Constructor.prototype; // 指向正确的原型
		var ret = Constructor.apply(obj, arguments); // 借用外部传入的构造器obj设置属性
		return typeof ret === 'object' ? ret : obj; // 确保构造器总是会返回一个对象
};
var a = objectFactory(Person, 'zee');
console.log(a.name);//zee
console.log(a.getName());//zee
console.log(Object.getProttotypeOf(a) === Person.prototype);//true
------------------------------------------------------------------
var a = objectFactory(A, 'zee');
var a = new A('zee');

3、对象会记住他的原型

var a = new Object();
console.log(a.__proto__ === Object.prototype);

实际上__proto__就是对象跟“对象构造器的原型”联系起来的纽带。正因为对象要通过__proto__属性来记住它的构造器的原型。

4、如果对象无法响应某个请求,它会把这个请求委托给它的构造器的原型

var obj = {name:'zee'};
var A = function(){};
A.prototype = obj;
var a = new A();
console.log(a.name);// zee

(1)首先,尝试遍历对象a中的所有属性,但没有找到name这个属性。
(2)查找name属性的这个请求被委托给对象a的构造器的原型,它被a.__proto__记录着并且指向A.prototype,而A.prototype被设置为对象obj。
(3)在对象obj中找到了name属性,并返回它的值。

ES6原型继承

class Animal {
	constructor(name){
		this.name = name;
	}
	getName(){
		return this.name;
	}
}
class Dog extends Animal {
	constructor(name){
		super(name);
	}
	speak(){
		return 'woof';
	}
}
var dog = new Dog('Scamp');
console.log(dog.getName() + 'says' + dog.speak());

猜你喜欢

转载自blog.csdn.net/HCJS_Zee/article/details/83004602