티스토리 뷰

  • A more efficient way is to set the prototypeto a new objectAdd the property numLegsand the two methods eat()and describe()to the prototypeof Dogby setting the prototypeto a new object.There is one crucial side effect of manually setting the prototypeto a new object. It erased the constructorproperty! To fix this, whenever a prototype is manually set to a new object, remember to define the constructorproperty:
  •  
  • Bird.prototype = { constructor: Bird, // define the constructor property numLegs: 2, eat: function() { console.log("nom nom nom"); }, describe: function() { console.log("My name is " + this.name); } };
  •  
  • Bird.prototype = { numLegs: 2, eat: function() { console.log("nom nom nom"); }, describe: function() { console.log("My name is " + this.name); } };
  • Understand the Prototype Chain
    Object.prototype.isPrototypeOf(Bird.prototype); // returns true 
    let duck = new Bird("Donald"); duck.hasOwnProperty("name"); // => true 
    The hasOwnPropertymethod is defined in Object.prototype, which can be accessed by Bird.prototype, which can then be accessed by duck. This is an example of the prototypechain.
  •  
  • All objects in JavaScript (with a few exceptions) have a prototype. Also, an object’s prototypeitself is an object. Because a prototypeis an object, a prototypecan have its own prototype! In this case, the prototypeof Bird.prototypeis Object.prototype:
  • Use Inheritance So You Don't Repeat YourselfThe describemethod is repeated in two places. The code can be edited to follow the DRYprinciple by creating a supertype(or parent) called Animal:Since Animalincludes the describemethod, you can remove it from Birdand Dog:How to reuse Animal'smethods inside Birdand Dogwithout defining them again. It uses a technique called inheritance. This challenge covers the first step: make an instance of the supertype(or parent).There are some disadvantages when using this syntax for inheritance, which are too complex for the scope of this challenge. Instead, here's an alternative approach without those disadvantages:Object.create(obj)creates a new object, and sets objas the new object's prototype. Recall that the prototypeis like the "recipe" for creating an object. By setting the prototypeof animalto be Animal's prototype, you are effectively giving the animalinstance the same "recipe" as any other instance of Animal.
    let duck = new Bird("Donald"); // 여기선 new operator을 썼다 duck.eat(); // prints "nom nom nom" 
    duckinherits all of Animal's properties, including the eatmethod.
  •  
  • Bird.prototype = Object.create(Animal.prototype);
  • let animal = Object.create(Animal.prototype);
  • let animal = new Animal();
  • Bird.prototype = { constructor: Bird }; Dog.prototype = { constructor: Dog };
  • function Animal() { }; Animal.prototype = { constructor: Animal, describe: function() { console.log("My name is " + this.name); } };
  • Bird.prototype = { constructor: Bird, describe: function() { console.log("My name is " + this.name); } }; Dog.prototype = { constructor: Dog, describe: function() { console.log("My name is " + this.name); } };
  • Reset an Inherited Constructor Property
    function Bird() { } Bird.prototype = Object.create(Animal.prototype); let duck = new Bird(); duck.constructor // function Animal(){...} 
    But duckand all instances of Birdshould show that they were constructed by Birdand not Animal. To do so, you can manually set Bird'sconstructor property to the Birdobject:
  • Bird.prototype.constructor = Bird; duck.constructor // function Bird(){...}
  • When an object inherits its prototypefrom another object, it also inherits the supertype's constructor property.
  • Add Methods After Inheritance
    function Animal() { } Animal.prototype.eat = function() {   console.log("nom nom nom"); }; function Bird() { } Bird.prototype = Object.create(Animal.prototype); Bird.prototype.constructor = Bird; 
    Bird.prototype.fly = function() {   console.log("I'm flying!"); }; 
    Now instances of Birdwill have both eat()and fly()methods:
  • es of Bird will have both eat() and fly() methods: let duck = new Bird(); duck.eat(); // prints "nom nom nom" duck.fly(); // prints "I'm flying!"
  • A constructor function that inherits its prototypeobject from a supertypeconstructor function can still have its own methods in addition to inherited methods.
  • Override Inherited Methods
    // Bird.eat() overrides Animal.eat() Bird.prototype.eat = function() {   return "peck peck peck"; };  let duck = new Bird(); 
    You call duck.eat(), this is how JavaScript looks for the method on duck’s``prototypechain:
    1. duck => Is eat() defined here? No.
    1. Bird => Is eat() defined here? => Yes. Execute it and stop searching.
    1. Animal => eat() is also defined, but JavaScript stopped searching before reaching this level.
    1. Object => JavaScript stopped searching before reaching this level.
  • Here's an example of Birdoverriding the eat()method inherited from Animal:

 

  • Use a Mixin to Add Common Behavior Between Unrelated Objects
    let flyMixin = function(obj) {     obj.fly = function() {         console.log("Flying, wooosh!");     } }; 
    The flyMixintakes any object and gives it the flymethod.
  • let bird = { name: "Donald", numLegs: 2 }; let plane = { model: "777", numPassengers: 524 }; flyMixin(bird); flyMixin(plane); bird.fly(); // prints "Flying, wooosh!" plane.fly(); // prints "Flying, wooosh!"
  • Here are cases when inheritance is not the best solution. Inheritance does not work well for unrelated objects like Birdand Airplane. They can both fly, but a Birdis not a type of Airplaneand vice versa. For unrelated objects, it's better to use mixins. A mixinallows other objects to use a collection of functions.
  • Use Closure to Protect Properties within an Object from Modified ExternallyThe simplest way to make properties private is by creating a variable within the constructor function. This changes the scope of that variable to be within the constructor function versus available globally. This way, the property can only be accessed and changed by methods also within the constructor function.Here getHachedEggCountis a privileged method, because it has access to the private variable hatchedEgg. This is possible because hatchedEggis declared in the same context as getHachedEggCount. In JavaScript, a function always has access to the context in which it was created. This is called closure.
  •  
  • function Bird() { let hatchedEgg = 10; // private property this.getHatchedEggCount = function() { return hatchedEgg; }; } let ducky = new Bird(); ducky.getHatchedEggCount(); // returns 10
  • In the previous challenge, birdhad a public property name. It is considered public because it can be accessed and changed outside of bird's definition.
  • IIFE(Immediately Invoked Function Expression)Note that the function has no name and is not stored in a variable.An immediately invoked function expression(IIFE) is often used to group related functionality into a single object or moduleThe advantage of the modulepattern is that all of the motion behaviors can be packaged into a single object that can then be used by other parts of your code. Here is an example using it:
  • motionModule.glideMixin(duck); duck.glide();
  • let motionModule = (function(){ return { glideMixin: function(obj) { obj.glide = function() { console.log("Gliding on the water"); }; }, flyMixin: function(obj) { obj.fly = function() { console.log("Flying, wooosh!"); } } } })(); // 2개의 mixin을 동시에
  •  
  • (function () { console.log("Chirp, chirp!"); })(); // this is an anonymous function expression that executes right away // Outputs "Chirp, chirp!" immediately

 

'공부일지(TIL) > JavaScript' 카테고리의 다른 글

How JS works? (Asynchronous Programming)  (0) 2019.03.19
Prototype(프로토타입)  (0) 2019.03.14
ES7, ES8  (0) 2019.03.08
pass by reference, shallow copy  (0) 2019.03.08
Currying, Compose, Deterministic  (0) 2019.03.07
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/12   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31
글 보관함