Prototypes

Exercise 1: Basics

First make a constructor named Ctor for an object that has properties a and b and initializes them to 0 and 1 respectively.

Now, make two objects named obj1 and obj2 using Ctor.

Now check the properties of a new object obj3 made this way:

varobj3={};Ctor.call(obj3);

Next, add a property c to obj1 with a value of 2. What will be the value of obj2.c?

Now, add a property d with the value 3 to obj1's "proto" (the object which helps out when obj1 can't do something by itself). Remember that there are at least four ways of referring to that proto object.

What are the values of obj1.d, obj2.d, and obj3.d? Can you explain the results?

Exercise 2: Deque Class

Write a constructor which constructs a special kind of object called a 'deque' (short for 'Double-Ended-QUEue'). A deque is like an array, but it can only be accessed from its two ends, like a roll of mints. Each deque instance should have a property holding an array and should have four methods:

deque.push(item)deque.pop()deque.unshift(item)deque.shift()

Each deque's array will be a personal property installed by the constructor, but its methods should be shared by all deque instances. Attach the methods to Deque's prototype so that they will be inherited by the instances. Each method will use 'this' to refer to the deque instance, then make a change to that deque's array using the array method of the same name.

Exercise 3: Modifying Prototypes

Consider this code:

functionA(){};//set default values for instances of A:A.prototype={num:0,str:'default'};varobjA=newA();functionB(){};// set default values for instances of B:B.prototype.num=0;B.prototype.str='default';varobjB=newB();

There is a difference between the behaviors of objA and objB! Explain.

Exercise 4: Implementing Inheritance

Here is a module (IIFE) which provides a constructor Rect which builds rectangle instances. The instance methods are shared but linked directly to each instance.

Modify the Rect module so that the instance method area is inherited from a prototype.

In a new IIFE, implement a subclass of Rect called Square. The Square constructor needs only one parameter: Square(size), and it should call the parent class constructor (Rect(width,height)) to set the new instance's properties.
A Square instance should inherit the area method of Rectangles without needing any changes.

Within the Square module, add an inheritable instance method size which acts as both a getter and setter for a square's size. That is, square.size() should return the current size of square, and square.size(num) should set the size to num.

For the moment, disable your Square module (by commenting it out or disabling the call operator () which triggers the IIFE).
Now Modify the Rect module so that the Rect constructor maintains a list of every instance it ever creates. Attach a class method every to constructor Rect which returns that list.

Now reactivate your Square module and then re-run the sequence above. What is the value of all[0]===r1? What happened?

Notice that constructor Square does not inherit the class method from its parent class Rect! Implement the class method every for Square as well, so that Square.every() will return all squares ever built.

Object.create

Modify constructor Square to use Object.create instead of new Rect when making Square's prototype. Does that fix the problem in #5 above?

Return to your earlier simulation of the new operator, which we approximated like this:

Exercise 5: Imaginary Menagerie

a) Implement a simple taxonomy of four related classes, using a constructor for each:

Animal: every instance of an Animal should inherit a method called move(). For basic animals, this just returns the string "walk". This method will be overridden by subclasses of Animal.

Bird: A subclass of Animal. Every Bird instance should return "fly" instead of "walk" when asked to move(). All Birds also inherit a property hasWings which is true.

Fish: Another subclass of Animal. A Fish instance will "swim" instead of "walk".

Penguin: A subclass of Bird. Penguins cannot fly and they should move like Fish.

Every instance of Animal and its subclasses should also have a personal name property which is not inherited. It should be set only within the constructor Animal, and each subclass constructor should first call its superclass constructor as an initializer, all the way up to Animal.

b) Create a class Egg, whose instances have one method, hatch(name), which returns a new instance (named name) of the same species which laid the egg.
Assume that every Animal can lay an egg with an instance method layEgg() which creates a new Egg instance.
Try to solve this without subclassing Egg and without implementing layEgg and hatch more than once.