JavaScriptãããã¿ã€ããã§ãŒã³å®å šã¬ã€ã
JavaScriptã®ãããã¿ã€ããã§ãŒã³ã®æ žå¿æŠå¿µããå®è·µçãªæŽ»çšãŸã§ïŒã¡ã¢ãªå¹çã®è¯ãç¶æ¿æ§é ãšprototypeãprotoã®éããã³ãŒãäŸã§åããããã解説ããŸãã
JavaScriptãæ±ãéçºè ãªãå¿ ãçè§£ãã¹ãæŠå¿µã®äžã€ãããŸãã«ãããã¿ã€ããã§ãŒã³ã§ãããã®ã¡ã«ããºã ã¯JavaScriptã®ãªããžã§ã¯ãæåããã°ã©ãã³ã°ã®æ žå¿ã§ãããã³ãŒãã®åå©çšæ§ãšã¡ã¢ãªå¹çãå€§å¹ ã«åäžãããããšãã§ããŸãã
å€ãã®éçºè ãES6ã®ã¯ã©ã¹æ§æã«æ £ãããããã¿ã€ãã®éèŠæ§ãèŠéãããã¡ã§ããããããã¯ã©ã¹æ§æãå éšçã«ã¯ãããã¿ã€ããæŽ»çšããŠããããããããã¿ã€ããã§ãŒã³ãæ£ããçè§£ããã°ãJavaScriptã®åäœåçãããæ·±ãææ¡ã§ããŸããã
ãã®èšäºã§ã¯ããããã¿ã€ããã§ãŒã³ã®åºæ¬æŠå¿µããå®éã®æŽ»çšæ¹æ³ãŸã§ãå®åã§ããã«å¿çšã§ããå å®¹ãæ±ã£ãŠãããŸããã³ãŒãäŸãšå ±ã«æ®µéçã«èª¬æããŸãã®ã§ãæåŸãŸã§ã€ããŠããã°ãããªãããããã¿ã€ããã§ãŒã³ãã¹ã¿ãŒã«ãªããã¯ãã§ãïŒ
JavaScriptãšãªããžã§ã¯ãæåããã°ã©ãã³ã°ã®åºäŒã
JavaScriptã¯ãã«ããã©ãã€ã èšèªã§ãã颿°åããã°ã©ãã³ã°ãå¯èœã§ããããªããžã§ã¯ãæåããã°ã©ãã³ã°ããµããŒãããŠããŸããããããJavaãC++ã®ãããªäŒçµ±çãªãªããžã§ã¯ãæåèšèªãšã¯ç°ãªãæ¹åŒãæ¡çšããŠããŸãã
äŒçµ±çãªãªããžã§ã¯ãæåèšèªã¯ã¯ã©ã¹ããŒã¹ã®ç¶æ¿ã䜿çšããŸããã¯ã©ã¹ãšããèšèšå³ãäœæãããã®èšèšå³ãåºã«ãªããžã§ã¯ããçæããæ¹åŒã§ãããäžæ¹ãJavaScriptã¯ãããã¿ã€ãããŒã¹ã®ç¶æ¿ã䜿çšããŸãã
// äŒçµ±çãªã¯ã©ã¹ããŒã¹èšèªã®æŠå¿µïŒå®éã®JavaScriptã³ãŒãã§ã¯ãããŸããïŒ
class Animal {
constructor(name) {
this.name = name;
}
speak() {
console.log(`${this.name}ã鳎ããŸãã`);
}
}
// JavaScriptã®ãããã¿ã€ãããŒã¹ã®ã¢ãããŒã
function Animal(name) {
this.name = name;
}
Animal.prototype.speak = function() {
console.log(`${this.name}ã鳎ããŸãã`);
};
JavaScriptã§ã¯ããã¹ãŠã®ãªããžã§ã¯ããä»ã®ãªããžã§ã¯ãããçŽæ¥ç¶æ¿ã§ããŸããããããããããã¿ã€ãããŒã¹ããã°ã©ãã³ã°ã®æ žå¿ã§ãã
ãããã¿ã€ãããŒã¹ããã°ã©ãã³ã°ãšã¯ïŒ
ãããã¿ã€ãããŒã¹ããã°ã©ãã³ã°ã¯ãã¯ã©ã¹ãªãã§ãªããžã§ã¯ããçæããç¶æ¿ãå®è£ ã§ããããã°ã©ãã³ã°ãã©ãã€ã ã§ããJavaScriptã§ã¯ããã¹ãŠã®ãªããžã§ã¯ããä»ã®ãªããžã§ã¯ããåç §ã§ããé ããªã³ã¯ãæã£ãŠããŸãã
ãããã¿ã€ãããŒã¹ããã°ã©ãã³ã°ã®ç¹åŸŽ
- åçç¶æ¿: å®è¡æã«ãªããžã§ã¯ãã®ãããã¿ã€ãã倿Žã§ããŸãã
- æè»æ§: ã¯ã©ã¹å®£èšãªãã§ãªããžã§ã¯ãéã®ç¶æ¿é¢ä¿ãæ§ç¯ã§ããŸãã
- ã¡ã¢ãªå¹ç: å ±éã®ã¡ãœããããããã¿ã€ãã§å ±æããã¡ã¢ãªãç¯çŽã§ããŸãã
// ãããã¿ã€ãããŒã¹ç¶æ¿ã®äŸ
const animal = {
type: 'åç©',
speak() {
console.log(`${this.name}ã¯${this.type}ã§ãã`);
}
};
const dog = Object.create(animal);
dog.name = 'ã¯ã³ã¡ãã';
dog.breed = 'çå³¶ç¬';
dog.speak(); // "ã¯ã³ã¡ããã¯åç©ã§ãã"
ãã®æ¹åŒã®å©ç¹ã¯ãéåžžã«æè»ã§ããããšã§ããå¿ èŠã«å¿ããŠãªããžã§ã¯ãã®æ§é ãåçã«å€æŽã§ããè€éãªã¯ã©ã¹éå±€ãªãã§ç¶æ¿ãå®è£ ã§ããŸãã
颿°ã®prototypeããããã£ãæ·±ãæãäžãã
JavaScriptã«ãããŠã颿°ã¯ç¹å¥ãªãªããžã§ã¯ãã§ãããã¹ãŠã®é¢æ°ã¯prototypeãšããããããã£ãæã£ãŠããŸãããã®prototypeããããã£ã¯ããã®é¢æ°ãã³ã³ã¹ãã©ã¯ã¿ãšããŠäœ¿çšãããéã«äœããããªããžã§ã¯ããç¶æ¿ãããããã¿ã€ããªããžã§ã¯ããæããŸãã
function Person(name) {
this.name = name;
}
console.log(Person.prototype); // {constructor: Æ}
console.log(typeof Person.prototype); // "object"
颿°ãçæããããšãJavaScriptãšã³ãžã³ã¯èªåçã«ãã®é¢æ°ã®prototypeãªããžã§ã¯ããäœæããŸãããã®ãããã¿ã€ããªããžã§ã¯ãã¯ãåºæ¬çã«ã¯constructorããããã£ã®ã¿ãæã£ãŠããŸãã
prototypeããããã£ã®æŽ»çš
prototypeããããã£ã掻çšãããšãã³ã³ã¹ãã©ã¯ã¿é¢æ°ã§äœã£ããã¹ãŠã®ã€ã³ã¹ã¿ã³ã¹ãå
±éããŠäœ¿çšã§ããã¡ãœãããããããã£ãå®çŸ©ã§ããŸãã
function Car(brand, model) {
this.brand = brand;
this.model = model;
}
// ãããã¿ã€ãã«ã¡ãœããã远å
Car.prototype.getInfo = function() {
return `${this.brand} ${this.model}`;
};
Car.prototype.start = function() {
console.log(`${this.getInfo()}ã®ãšã³ãžã³ããããŸãã`);
};
const myCar = new Car('ãã¥ã³ãã€', 'ãœãã¿');
const yourCar = new Car('ãã¢', 'K5');
myCar.start(); // "ãã¥ã³ã〠ãœãã¿ã®ãšã³ãžã³ããããŸãã"
yourCar.start(); // "ã㢠K5ã®ãšã³ãžã³ããããŸãã"
// 2ã€ã®ãªããžã§ã¯ããåãã¡ãœãããå
±æããŠããã確èª
console.log(myCar.start === yourCar.start); // true
ãã®æ¹åŒã®å€§ããªå©ç¹ã¯ã¡ã¢ãªå¹çã§ããããåã€ã³ã¹ã¿ã³ã¹ããšã«ã¡ãœãããåå¥ã«å®çŸ©ãããšãã€ã³ã¹ã¿ã³ã¹ã®æ°ã ãã¡ãœãããã¡ã¢ãªäžã«çæãããŠããŸããŸãããããããããããã¿ã€ãã䜿ãã°ãäžã€ã®ã¡ãœããããã¹ãŠã®ã€ã³ã¹ã¿ã³ã¹ã§å ±æã§ããŸãã
__proto__ãš[[Prototype]]å éšã¹ãããã®çè§£
JavaScriptã®ãã¹ãŠã®ãªããžã§ã¯ãã¯[[Prototype]]ãšããå
éšã¹ããããæã£ãŠããŸããããã¯ããã®ãªããžã§ã¯ãã®ãããã¿ã€ããæãé ããããªã³ã¯ã§ããå€ãã®ãã©ãŠã¶ã§ã¯ããã®å
éšã¹ãããã«__proto__ãšããããããã£ã§ã¢ã¯ã»ã¹ã§ããããã«ãªã£ãŠããŸãã
__proto__ãšprototypeã®éã
ãã®äºã€ã¯æ··åãããã¡ã§ãããæç¢ºã«åºå¥ããå¿ èŠããããŸããã
function Animal(name) {
this.name = name;
}
const dog = new Animal('ã¯ã³ã¡ãã');
// prototype: 颿°ã®ããããã£ïŒã³ã³ã¹ãã©ã¯ã¿é¢æ°ã«ã®ã¿ååšïŒ
console.log(Animal.prototype); // {constructor: Æ}
// __proto__: ãªããžã§ã¯ãã®ããããã£ïŒãã¹ãŠã®ãªããžã§ã¯ãã«ååšïŒ
console.log(dog.__proto__); // {constructor: Æ}
// ãã®äºã€ã¯åããªããžã§ã¯ããæããŸã
console.log(Animal.prototype === dog.__proto__); // true
å®éã®ãããã¿ã€ããã§ãŒã³ã®ç¢ºèª
function Shape(type) {
this.type = type;
}
Shape.prototype.getType = function() {
return this.type;
};
function Circle(radius) {
Shape.call(this, 'å');
this.radius = radius;
}
// CircleãShapeãç¶æ¿ããããã«èšå®
Circle.prototype = Object.create(Shape.prototype);
Circle.prototype.constructor = Circle;
Circle.prototype.getArea = function() {
return Math.PI * this.radius * this.radius;
};
const myCircle = new Circle(5);
// ãããã¿ã€ããã§ãŒã³ã®ç¢ºèª
console.log(myCircle.__proto__ === Circle.prototype); // true
console.log(myCircle.__proto__.__proto__ === Shape.prototype); // true
console.log(myCircle.__proto__.__proto__.__proto__ === Object.prototype); // true
ãããã¿ã€ããã§ãŒã³ã®åäœåç
ãããã¿ã€ããã§ãŒã³ã¯ãJavaScriptããªããžã§ã¯ãã®ããããã£ãã¡ãœãããæ¢ãã¡ã«ããºã ã§ãã察象ã®ãªããžã§ã¯ãã«ç®çã®ããããã£ããªããã°ããããã¿ã€ããã§ãŒã³ããã©ã£ãŠæ¢ãã«è¡ããŸãã
ããããã£æ€çŽ¢ããã»ã¹
- ãŸããªããžã§ã¯ãèªèº«ã®ããããã£ããæ€çŽ¢
- ãªããã°
__proto__ãæããããã¿ã€ããªããžã§ã¯ãã§æ€çŽ¢ - ããã§ããªããã°ããã®ãããã¿ã€ãã®ãããã¿ã€ãã§æ€çŽ¢
Object.prototypeãŸã§ãã©ã£ãŠããªããã°undefinedãè¿ã
function Animal(name) {
this.name = name;
}
Animal.prototype.speak = function() {
console.log(`${this.name}ã鳎ããŸãã`);
};
function Dog(name, breed) {
Animal.call(this, name);
this.breed = breed;
}
Dog.prototype = Object.create(Animal.prototype);
Dog.prototype.constructor = Dog;
Dog.prototype.bark = function() {
console.log('ã¯ã³ã¯ã³ïŒ');
};
const myDog = new Dog('ãã', 'çå³¶ç¬');
// ããããã£æ€çŽ¢ããã»ã¹ã®ã·ãã¥ã¬ãŒã·ã§ã³
console.log(myDog.name); // 1段é: myDogãªããžã§ã¯ãã§çºèŠ - "ãã"
console.log(myDog.breed); // 1段é: myDogãªããžã§ã¯ãã§çºèŠ - "çå³¶ç¬"
myDog.bark(); // 2段é: Dog.prototypeã§çºèŠ - "ã¯ã³ã¯ã³ïŒ"
myDog.speak(); // 3段é: Animal.prototypeã§çºèŠ - "ããã鳎ããŸãã"
console.log(myDog.toString()); // 4段é: Object.prototypeã§çºèŠ
åçãªãããã¿ã€ã倿Ž
ãããã¿ã€ãã¯å®è¡æã«åçã«å€æŽã§ããŸããããã¯éåžžã«åŒ·åãªæ©èœã§ãããæ éã«äœ¿ãå¿ èŠããããŸãã
function User(name) {
this.name = name;
}
const user1 = new User('ãã ã»ãã§ã«ã¹');
const user2 = new User('ã€ã»ãšã³ã');
// åŸãããããã¿ã€ãã«ã¡ãœããã远å
User.prototype.greet = function() {
console.log(`ããã«ã¡ã¯ã${this.name}ã§ãã`);
};
// ãã§ã«çæããããªããžã§ã¯ããæ°ããã¡ãœããã䜿çšå¯èœ
user1.greet(); // "ããã«ã¡ã¯ããã ã»ãã§ã«ã¹ã§ãã"
user2.greet(); // "ããã«ã¡ã¯ãã€ã»ãšã³ãã§ãã"
ãããã¿ã€ããã§ãŒã³ã®å¶çŽãšæ³šæç¹
ãããã¿ã€ããã§ãŒã³ã¯åŒ·åã§ãããããã€ãã®å¶çŽãšæ³šæç¹ããããŸãã
埪ç°åç §ã®é²æ¢
JavaScriptã¯ãããã¿ã€ããã§ãŒã³ã§ã®åŸªç°åç §ãèš±å¯ããŸããã
const obj1 = {};
const obj2 = {};
obj1.__proto__ = obj2;
// obj2.__proto__ = obj1; // TypeError: Cyclic __proto__ value
ããã©ãŒãã³ã¹ã«é¢ããèæ ®äºé
ãããã¿ã€ããã§ãŒã³ãé·ããªãã»ã©ãããããã£ã®æ€çŽ¢æéãå¢å ããŸããç¹ã«é »ç¹ã«ã¢ã¯ã»ã¹ããããããã£ã®å Žåãããã©ãŒãã³ã¹ã«åœ±é¿ãäžããå¯èœæ§ããããŸãã
// ããã©ãŒãã³ã¹ã®ããã®ãã£ãã·ã³ã°äŸ
function ExpensiveOperation() {}
ExpensiveOperation.prototype.calculate = function() {
if (this._cachedResult) {
return this._cachedResult;
}
// è€éãªèšç®ãå®è¡
this._cachedResult = Math.random() * 1000;
return this._cachedResult;
};
const operation = new ExpensiveOperation();
console.log(operation.calculate()); // æåã®åŒã³åºãïŒèšç®å®è¡
console.log(operation.calculate()); // 2åç®ã®åŒã³åºãïŒãã£ãã·ã¥ãããçµæãè¿ã
ããããã£ã®å€æŽãšåé€ã®å¶é
ãããã¿ã€ããã§ãŒã³ãéããŠã¢ã¯ã»ã¹ããããããã£ã¯èªã¿åãå°çšã§ããã倿Žãåé€ã¯å¯Ÿè±¡ã®ãªããžã§ã¯ãã«çŽæ¥äœçšããŸãã
const parent = { x: 1 };
const child = Object.create(parent);
console.log(child.x); // 1 (parentããç¶æ¿)
child.x = 2; // childãªããžã§ã¯ãã«æ°ããxããããã£ãçæããã
console.log(child.x); // 2
console.log(parent.x); // 1 (倿Žãããªã)
delete child.x;
console.log(child.x); // 1 (åã³parentããç¶æ¿)
ã¯ã©ã¹ããŒã¹ vs ãããã¿ã€ãããŒã¹ã®ç¶æ¿æ¯èŒ
ES6ã§å°å ¥ãããã¯ã©ã¹æ§æãšãäŒçµ±çãªãããã¿ã€ãããŒã¹ã®ç¶æ¿ãæ¯èŒããŠã¿ãŸãããã
ã¯ã©ã¹æ§æ (ES6+)
class Animal {
constructor(name) {
this.name = name;
}
speak() {
console.log(`${this.name}ã鳎ããŸãã`);
}
}
class Dog extends Animal {
constructor(name, breed) {
super(name);
this.breed = breed;
}
bark() {
console.log('ã¯ã³ã¯ã³ïŒ');
}
}
const myDog = new Dog('ãã', 'çå³¶ç¬');
ãããã¿ã€ãããŒã¹ã®å®è£
function Animal(name) {
this.name = name;
}
Animal.prototype.speak = function() {
console.log(`${this.name}ã鳎ããŸãã`);
};
function Dog(name, breed) {
Animal.call(this, name);
this.breed = breed;
}
Dog.prototype = Object.create(Animal.prototype);
Dog.prototype.constructor = Dog;
Dog.prototype.bark = function() {
console.log('ã¯ã³ã¯ã³ïŒ');
};
const myDog = new Dog('ãã', 'çå³¶ç¬');
åæ¹åŒã®é·æãšçæ
ã¯ã©ã¹æ§æã®é·æ:
- æ§æãçŽæçã§èªã¿ããã
- ä»ã®ãªããžã§ã¯ãæåèšèªãšäŒŒãæ§é
superããŒã¯ãŒãã§èŠªã¯ã©ã¹ãžã®ã¢ã¯ã»ã¹ã容æ
ãããã¿ã€ãããŒã¹ã®é·æ:
- ããæè»ãªç¶æ¿æ§é
- ã©ã³ã¿ã€ã ã§åçã«ç¶æ¿é¢ä¿ã倿Žå¯èœ
- ã¡ã¢ãªå¹çããã现ããå¶åŸ¡å¯èœ
ãããã¿ã€ããã§ãŒã³ã®å®çšçãªå©ç¹
ã¡ã¢ãªç¯çŽãšããã©ãŒãã³ã¹æé©å
ãããã¿ã€ããæŽ»çšãããšãã¡ãœããããã¹ãŠã®ã€ã³ã¹ã¿ã³ã¹ã§å ±æãããããã¡ã¢ãªãå¹ççã«äœ¿çšã§ããŸãã
// éå¹çãªæ¹æ³
function User(name) {
this.name = name;
this.greet = function() { // åã€ã³ã¹ã¿ã³ã¹ããšã«é¢æ°ãçæ
console.log(`ããã«ã¡ã¯ã${this.name}ã§ãã`);
};
}
// å¹ççãªæ¹æ³
function User(name) {
this.name = name;
}
User.prototype.greet = function() { // ãã¹ãŠã®ã€ã³ã¹ã¿ã³ã¹ãå
±æ
console.log(`ããã«ã¡ã¯ã${this.name}ã§ãã`);
};
// ã¡ã¢ãªäœ¿çšéã®æ¯èŒ
const users1 = Array(1000).fill().map((_, i) => new User(`ãŠãŒã¶ãŒ${i}`));
// æåã®æ¹æ³ïŒ1000åã®greet颿°ãã¡ã¢ãªã«çæããã
// 2çªç®ã®æ¹æ³ïŒ1åã®greet颿°ããã¹ãŠã®ã€ã³ã¹ã¿ã³ã¹ãå
±æ
ã³ãŒãã®åå©çšæ§åäž
ãããã¿ã€ããã§ãŒã³ã掻çšãããšãå ±éã®æ©èœãç°¡åã«åå©çšã§ããŸãã
// å
±éæ©èœãæã€åºæ¬ã¯ã©ã¹
function BaseEntity() {}
BaseEntity.prototype.save = function() {
console.log(`${this.constructor.name}ãä¿åããŸãã`);
};
BaseEntity.prototype.delete = function() {
console.log(`${this.constructor.name}ãåé€ããŸãã`);
};
// ç¹åããã¯ã©ã¹çŸ€
function User(name) {
this.name = name;
}
User.prototype = Object.create(BaseEntity.prototype);
User.prototype.constructor = User;
function Product(name, price) {
this.name = name;
this.price = price;
}
Product.prototype = Object.create(BaseEntity.prototype);
Product.prototype.constructor = Product;
const user = new User('ãã ã»ãã§ã«ã¹');
const product = new Product('ããŒãPC', 1000000);
user.save(); // "Userãä¿åããŸãã"
product.delete(); // "Productãåé€ããŸãã"
ãããã¿ã€ã管çã¡ãœãã
Object.getPrototypeOfãšObject.setPrototypeOf
ãããã®ã¡ãœããã䜿çšããŠããªããžã§ã¯ãã®ãããã¿ã€ããå®å šã«ç §äŒãã倿Žããããšãã§ããŸãã
const animal = {
type: 'åç©',
speak() {
console.log(`${this.name}ã¯${this.type}ã§ãã`);
}
};
const dog = { name: 'ã¯ã³ã¡ãã' };
// ãããã¿ã€ããèšå®
Object.setPrototypeOf(dog, animal);
// ãããã¿ã€ããç
§äŒ
console.log(Object.getPrototypeOf(dog) === animal); // true
dog.speak(); // "ã¯ã³ã¡ããã¯åç©ã§ãã"
Object.createã®æŽ»çš
Object.createã¯ãæå®ããããããã¿ã€ããæã€æ°ãããªããžã§ã¯ããçæããæãã¯ãªãŒã³ãªæ¹æ³ã§ãã
const vehiclePrototype = {
start() {
console.log(`${this.brand} ${this.model}ã®ãšã³ãžã³ããããŸãã`);
},
stop() {
console.log(`${this.brand} ${this.model}ã®ãšã³ãžã³ãåããŸãã`);
}
};
// ãããã¿ã€ããæå®ããŠãªããžã§ã¯ããçæ
const car = Object.create(vehiclePrototype, {
brand: { value: 'ãã¥ã³ãã€', writable: true },
model: { value: 'ãœãã¿', writable: true },
year: { value: 2023, writable: true }
});
car.start(); // "ãã¥ã³ã〠ãœãã¿ã®ãšã³ãžã³ããããŸãã"
ãããã¿ã€ããã§ãŒã³ã®å®å šãªæ¢çŽ¢
function walkPrototypeChain(obj) {
const chain = [];
let current = obj;
while (current !== null) {
chain.push(current.constructor?.name || 'Anonymous');
current = Object.getPrototypeOf(current);
}
return chain;
}
function Animal(name) { this.name = name; }
function Dog(name, breed) {
Animal.call(this, name);
this.breed = breed;
}
Dog.prototype = Object.create(Animal.prototype);
Dog.prototype.constructor = Dog;
const myDog = new Dog('ãã', 'çå³¶ç¬');
console.log(walkPrototypeChain(myDog));
// ['Dog', 'Animal', 'Object']
å®è·µçãªãããã¿ã€ãç¶æ¿ã®æŽ»çšäŸ
ãã©ã°ã€ã³ã·ã¹ãã ã®å®è£
// åºæ¬ãã©ã°ã€ã³ã¯ã©ã¹
function Plugin(name) {
this.name = name;
this.enabled = false;
}
Plugin.prototype.enable = function() {
this.enabled = true;
console.log(`${this.name}ãã©ã°ã€ã³ãæå¹åãããŸããã`);
};
Plugin.prototype.disable = function() {
this.enabled = false;
console.log(`${this.name}ãã©ã°ã€ã³ãç¡å¹åãããŸããã`);
};
// ç¹åãããã©ã°ã€ã³
function AuthPlugin() {
Plugin.call(this, 'Authentication');
}
AuthPlugin.prototype = Object.create(Plugin.prototype);
AuthPlugin.prototype.constructor = AuthPlugin;
AuthPlugin.prototype.authenticate = function(user) {
if (!this.enabled) {
throw new Error('èªèšŒãã©ã°ã€ã³ãç¡å¹åãããŠããŸãã');
}
console.log(`${user}ãŠãŒã¶ãŒãèªèšŒããŸãã`);
};
function LoggingPlugin() {
Plugin.call(this, 'Logging');
}
LoggingPlugin.prototype = Object.create(Plugin.prototype);
LoggingPlugin.prototype.constructor = LoggingPlugin;
LoggingPlugin.prototype.log = function(message) {
if (!this.enabled) return;
console.log(`[LOG] ${message}`);
};
// 䜿çšäŸ
const authPlugin = new AuthPlugin();
const loggingPlugin = new LoggingPlugin();
authPlugin.enable();
loggingPlugin.enable();
authPlugin.authenticate('ãã ã»ãã§ã«ã¹');
loggingPlugin.log('ãŠãŒã¶ãŒããã°ã€ã³ããŸããã');
ããã¯ã¹ã€ã³ãã¿ãŒã³ã®å®è£
// ããã¯ã¹ã€ã³ãªããžã§ã¯ã
const Flyable = {
fly() {
console.log(`${this.name}ãé£ã³ãŸãã`);
}
};
const Swimmable = {
swim() {
console.log(`${this.name}ãæ³³ããŸãã`);
}
};
// ããã¯ã¹ã€ã³ãé©çšãããã«ããŒé¢æ°
function mixin(target, ...sources) {
sources.forEach(source => {
Object.getOwnPropertyNames(source).forEach(name => {
if (name !== 'constructor') {
target.prototype[name] = source[name];
}
});
});
return target;
}
// åºæ¬åç©ã¯ã©ã¹
function Animal(name) {
this.name = name;
}
// ã¢ãã«ã¯ã©ã¹ïŒé£ã¶ããšãæ³³ãããšãã§ããïŒ
function Duck(name) {
Animal.call(this, name);
}
Duck.prototype = Object.create(Animal.prototype);
Duck.prototype.constructor = Duck;
// ããã¯ã¹ã€ã³é©çš
mixin(Duck, Flyable, Swimmable);
const donald = new Duck('ããã«ã');
donald.fly(); // "ããã«ããé£ã³ãŸãã"
donald.swim(); // "ããã«ããæ³³ããŸãã"
ãã³ã¬ãŒã¿ãŒãã¿ãŒã³ã®å®è£
// åºæ¬ã®ã³ãŒããŒã¯ã©ã¹
function Coffee() {
this.cost = 1000;
this.description = 'åºæ¬ã®ã³ãŒããŒ';
}
Coffee.prototype.getCost = function() {
return this.cost;
};
Coffee.prototype.getDescription = function() {
return this.description;
};
// ãã³ã¬ãŒã¿ãŒã®åºæ¬ã¯ã©ã¹
function CoffeeDecorator(coffee) {
this.coffee = coffee;
}
CoffeeDecorator.prototype.getCost = function() {
return this.coffee.getCost();
};
CoffeeDecorator.prototype.getDescription = function() {
return this.coffee.getDescription();
};
// å
·äœçãªãã³ã¬ãŒã¿ãŒ
function MilkDecorator(coffee) {
CoffeeDecorator.call(this, coffee);
}
MilkDecorator.prototype = Object.create(CoffeeDecorator.prototype);
MilkDecorator.prototype.constructor = MilkDecorator;
MilkDecorator.prototype.getCost = function() {
return this.coffee.getCost() + 500;
};
MilkDecorator.prototype.getDescription = function() {
return this.coffee.getDescription() + 'ããã«ã¯';
};
function SugarDecorator(coffee) {
CoffeeDecorator.call(this, coffee);
}
SugarDecorator.prototype = Object.create(CoffeeDecorator.prototype);
SugarDecorator.prototype.constructor = SugarDecorator;
SugarDecorator.prototype.getCost = function() {
return this.coffee.getCost() + 200;
};
SugarDecorator.prototype.getDescription = function() {
return this.coffee.getDescription() + 'ãç ç³';
};
// 䜿çšäŸ
let myCoffee = new Coffee();
myCoffee = new MilkDecorator(myCoffee);
myCoffee = new SugarDecorator(myCoffee);
console.log(myCoffee.getDescription()); // "åºæ¬ã®ã³ãŒããŒããã«ã¯ãç ç³"
console.log(myCoffee.getCost()); // 1700
ãããã¿ã€ããã§ãŒã³ããã¹ã¿ãŒãã
ãããã¿ã€ããã§ãŒã³ã¯ãJavaScriptã®æ žå¿æŠå¿µã®äžã€ã§ãããããæ£ããçè§£ããã°ãããå¹ççã§æè»ãªã³ãŒããæžãããšãã§ããŸãã
éèŠãªãã€ã³ãããŸãšãããšæ¬¡ã®ããã«ãªããŸãïŒ
- ãããã¿ã€ãããŒã¹ã®ç¶æ¿: JavaScriptã¯ã¯ã©ã¹ããŒã¹ã§ã¯ãªãããããã¿ã€ãããŒã¹ã®ç¶æ¿ã䜿çšããŸãã
- ã¡ã¢ãªå¹ç: ãããã¿ã€ããæŽ»çšããããšã§ã¡ãœãããå ±æããã¡ã¢ãªãç¯çŽã§ããŸãã
- åçãªç¹æ§: å®è¡æã«ãããã¿ã€ãã倿Žã§ããéåžžã«æè»ãªããã°ã©ãã³ã°ãå¯èœã§ãã
- ãã§ãŒã³æ¢çŽ¢: ããããã£ãæ€çŽ¢ããéããããã¿ã€ããã§ãŒã³ããã©ã£ãŠæ€çŽ¢ããã¡ã«ããºã ãçè§£ããå¿ èŠããããŸãã
- å®å
šãªäœ¿çš:
Object.getPrototypeOfãObject.setPrototypeOfãObject.createãªã©ã®ã¡ãœãããæŽ»çšããŠãå®å šã«ãããã¿ã€ãã管çã§ããŸãã
ãããã¿ã€ããã§ãŒã³ããã¹ã¿ãŒããã°ãES6ã®ã¯ã©ã¹æ§æãããæ·±ãçè§£ã§ããJavaScriptã©ã€ãã©ãªããã¬ãŒã ã¯ãŒã¯ã®å éšåäœåçãææ¡ãããããªããŸããå®åã§ééããè€éãªç¶æ¿æ§é ããã¶ã€ã³ãã¿ãŒã³ãèªä¿¡ãæã£ãŠæ±ããããã«ãªãã§ãããã
ä»ããããªãã®ãããžã§ã¯ãã§ãããã¿ã€ããã§ãŒã³ãç©æ¥µçã«æŽ»çšããŠã¿ãŠãã ãããããã¯ãªãŒã³ã§å¹ççãªã³ãŒããæžããããã«ãªãã¯ãã§ãïŒ