欢迎大家来到IT世界,在知识的湖畔探索吧!
在同一类的对象之间共享属性
原型模式用于在同一类型的对象之间共享属性。原型是JavaScript原生的一种对象,并且可以通过对象的原型链直接访问。
在应用中,我们通常会创建同一种类型的很多对性。通常我们会通过ES6的类定义来达成这一目的。
比如希望创建很多狗类对象,当然并不是创建了很多狗类:而是通过狗的类型定义,为不同的狗赋予不同的名字,并且,他们具有相同的行为,也就是犬吠。
class Dog { constructor(name) { this.name = name; } bark() { return `Woof!`; } } const dog1 = new Dog("Daisy"); const dog2 = new Dog("Max"); const dog3 = new Dog("Spot");
欢迎大家来到IT世界,在知识的湖畔探索吧!
请注意构造函数包含一个name属性,以及类定义中包含一个bark的属性。在ES6的类定义中,所有在类定义中声明的属性,比如在本例中的bark,都会被自动添加到prototype中。
如果要近距离观察prototype,可以通过类的构造函数中的prototype属性对其进行访问,或者通过任何实例的__proto__属性进行访问。
欢迎大家来到IT世界,在知识的湖畔探索吧!console.log(Dog.prototype); // constructor: ƒ Dog(name, breed) bark: ƒ bark() console.log(dog1.__proto__); // constructor: ƒ Dog(name, breed) bark: ƒ bark()
构造函数派生的任何实例的__proto__属性,都直接引用了构造函数的原型。当访问对象中不直接存在的属性时,JavaScript都会向上追溯整个原型链,看看是否在原型链的上游存在这个属性。
欢迎大家来到IT世界,在知识的湖畔探索吧!
class Dog { constructor(name) { this.name = name; } bark() { return `Woof!`; } } const dog1 = new Dog("Daisy"); const dog2 = new Dog("Max"); const dog3 = new Dog("Spot"); Dog.prototype.play = () => console.log("Playing now!"); dog1.play();原型链这个术语从字面上来看,既然是链条就意味着可以不仅有一层。确实如此!截止目前位置,我们都只讨论了在实例对象中的直接可见的__proto__属性。然而__proto__引用的原型本身也有一个__proto__对象。
为了验证这点,可以创建另一个类型的狗狗类声明:super dog。这类型的狗应该能够从普通的Dog类声明中继承其所有属性,与此同时它还能够飞。为了达成此目标,我们可以创建一个SuperDog类,扩展自Dog类,并且新添加一个fly方法。
欢迎大家来到IT世界,在知识的湖畔探索吧!class SuperDog extends Dog { constructor(name) { super(name); } fly() { return "Flying!"; } }
之后通过实例化SuperDog类,得到狗狗对象Daisy,这只新狗狗可以叫,并且能够飞翔。
class Dog { constructor(name) { this.name = name; } bark() { console.log("Woof!"); } } class SuperDog extends Dog { constructor(name) { super(name); } fly() { console.log(`Flying!`); } } const dog1 = new SuperDog("Daisy"); dog1.bark(); dog1.fly();
因为扩展了Dog类,所以实例可以调用bark方法。深层次的原因在于SuperDog的原型中的__proto__的引用正是指向了Dog.prototype对象。
关于所谓原型链的真相愈发明晰:当我们访问一个对象中并不直接存在于对象本身的属性时,JavaScript会递归地沿着原型链,通过访问原型链路径链路上所有的__proto__属性向上层的寻找,直到找到这一属性。
Object.create
Object.create方法允许通过它创建一个新的对象,通过这个方法可以明确地传递原型作为参数。
欢迎大家来到IT世界,在知识的湖畔探索吧!const dog = { bark() { return `Woof!`; } }; const pet1 = Object.create(dog);
虽然pet1对象本身并没有任何属性,但是由于我们向create方法传递了dog对象作为参数,因此pet1对象也获取了原型链上层对象的bark属性的访问能力。
const dog = { bark() { console.log(`Woof!`); } }; const pet1 = Object.create(dog); pet1.bark(); // Woof! console.log("Direct properties on pet1: ", Object.keys(pet1)); console.log("Properties on pet1's prototype: ", Object.keys(pet1.__proto__));
Object.create通过明确新创建的实例来自于哪个对象原型,可以明确新创建的对象能够继承哪个对象的属性。所以新创建的对象可以访问原型链上游的属性。
原型模式可以让使用者轻松的继承和访问其他对象的属性。由于原型链允许访问那些并不在类本身定义过的属性,所以也就避免了重复声明方法和属性,最终在运行时节约了内存消耗。
原文地址:https://www.patterns.dev/posts/prototype-pattern/
免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://itzsg.com/90124.html