版权声明:本文为博主原创文章,未经博主允许不得转载。 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());