Object Creation Patterns Flashcards
2 disadvantages of factory functions
Each object created by the factory function has a copy of all the methods, which can be redundant and memory intensive.
(basically the benefit of prototypes)
There is no way to tell which factory function created an object, so there’s no way to be sure that you’re working with the right kind of object.
(which is the benefit of constructors)
Problems 3 -5
https://launchschool.com/lessons/e3c64e3f/assignments/bf77a962
https://launchschool.com/lessons/e3c64e3f/assignments/bf77a962
The object oriented code makes these questions easier to answer (5 things, 3 chunks)
How do we create that object?
Where should we add new properties and methods?
What are the properties of any given object?
What operations can I perform on that vehicle?
What are the important concepts in the program?
Describe the constructor algorithm (5 things)
1 It creates an entirely new object.
2 It sets Constructor.prototype as the prototype for the new object. That is, the new object inherits from the object referenced by Constructor.prototype.
3 It sets the value of this for use inside the function to point to the new object.
4 It invokes the function. Since this refers to the new object, we use it within the function to set the object’s properties and methods.
5 Finally, once the function finishes running, new returns the new object even though we don’t explicitly return anything. If something is returned the object is returned instead. If ANOTHER object is returned, that OTHER object is returned instead
What happens if you invoke a constructor function without the new keyword?
It executes the function body as normal. But without assigning this to a newly created object, “this” applies to the global object. So it puts a bunch of new properties on the global object.
What happens with this:
let apple = () => {
this.apple = “sauce”;
};
let applesauce = new apple();
Type Error
What happens with this:
let foo = {
Car: function(make, model, year) {
this.make = make;
this.model = model;
this.year = year;
}
};
let car1 = new foo.Car(‘Toyota’, ‘Camry’, 2019);
car1.make;
//=> ‘Toyota’
What happens with this?
let foo = {
Car(make, model, year) {
this.make = make;
this.model = model;
this.year = year;
}
};
new foo.Car();
//=> Uncaught TypeError: foo.Car is not a constructor
concise syntax (also called a concise method) won’t work.
ie. Car(make, model, year) vs Car: function(make, model, year)
new doesn’t work with these T or F
new console.log();
new Math();
new parseInt(“3”);
new Date();
T
//=> Uncaught TypeError: console.log is not a constructor
for the first 3,
but it works with Date();
//=> 2019-06-26T02:50:20.191Z
What happens with
function Cat(name, breed, weight) {
this.name = name;
this.breed = breed;
this.weight = weight;
return ‘a cat’;
}
let fluffy = new Cat(‘fluffy’, ‘Persian’, 15);
fluffy.weight;
// 15
The rule here is that if a constructor explicitly tries to return an object, then that object is returned instead of the new object created with the use of new. In all other situations, it returns the newly created object, provided no errors occur. In particular, the constructor ignores explicit return values that are primitives.
What happens with
function Cat(name, breed, weight) {
this.name = name;
this.breed = breed;
this.weight = weight;
return { foo: 1 };
}
let fluffy = new Cat(‘fluffy’, ‘Persian’, 15);
fluffy.weight;
fluffy.foo;
// undefined
// 1
The rule here is that if a constructor explicitly tries to return an object, then that object is returned instead of the new object created with the use of new. In all other situations, it returns the newly created object, provided no errors occur. In particular, the constructor ignores explicit return values that are primitives.
How to avoid this noise:
function Car(make, model, year, color, passengers, convertible, mileage) {
this.make = make;
this.model = model;
this.year = year;
this.color = color;
this.passengers = passengers;
this.convertible = convertible;
this.mileage = mileage;
this.started = false;
this.drive = function() {
this.started = true;
};
// rest of the methods
}
One common technique that we can use to manage our parameters better involves passing them to our constructor with an object argument:
let civicArgs = {
make: ‘Honda’,
model: ‘Civic’,
year: 2016,
color: ‘black’,
passengers: 5,
convertible: false,
mileage: 16000
}
let civic = new Car(civicArgs);
If we use an object as our constructor argument
How can we avoid this noise?
function Car(args) {
this.make = args.make;
this.model = args.model;
this.year = args.year;
this.color = args.color;
this.passengers = args.passengers;
this.convertible = args.convertible;
this.mileage = args.mileage;
this.started = false;
this.drive = function() {
this.started = true;
};
// rest of methods
}
Object.assign
function Car(args) {
Object.assign(this, args);
this.drive = function() {
this.started = true;
};
// rest of the methods
}
Issue with the object.assign method inside the constructor function
However, one drawback of the Object.assign approach is that the args object may contain properties that the Car object doesn’t need. Those additional properties will, nevertheless, get added to the Car object. Those properties may just be excess baggage for the objects to carry around, but they may also cause trouble.
Return boolean if an object was created using a specific constructor function
object instanceof Constructor
ex:
civic instanceof Car
What is the implicit execution context of a method inside an object created with a contstructor?
The new object
What happens with:
function Lizard() {
this.scamper = function() {
console.log(“I’m scampering!”);
};
}
let lizzy = Lizard();
lizzy.scamper(); // ?
Type error
undefined.undefined is what it’s tryin to do
Create a constructor function that defines the prototype to something othe than default
let DogPrototype = {
bark() {
console.log(this.weight > 20 ? ‘Woof!’ : ‘Yip!’);
}
};
function Dog(name, breed, weight) {
Object.setPrototypeOf(this, DogPrototype);
this.name = name;
this.breed = breed;
this.weight = weight;
// this.bark method removed.
}
Make a constructor function that “defines the prototype”, but use the native prototype setting functionality of constructor functions
function Dog(name, breed, weight) {
// deleted Object.setPrototypeOf(this, Dog.myPrototype);
this.name = name;
this.breed = breed;
this.weight = weight;
}
Dog.prototype.bark = function() {
console.log(this.weight > 20 ? ‘Woof!’ : ‘Yip!’);
};
let maxi = new Dog(‘Maxi’, ‘German Shepherd’, 32);
maxi.bark(); // ‘Woof!’
let biggie = new Dog(‘Biggie’, ‘Whippet’, 9);
biggie.bark(); // ‘Yip!’
What’s the difference between an object prototype and a function prototype?
The object prototype is just a prototype for an object.
Ex.
If bar is an object, then the object from which bar inherits is the object prototype.
The function prototype is the constructor’s prototype object, exists on ConstructorObject.prototype. Any objects created by this constructor have their prototype set to the constructor’s prototype object.
Ex:
if the constructor’s name is Foo, then Foo.prototype references the constructor’s prototype object
By default, constructor functions set the object prototype for the objects they create to Object.prototype.
T or F
F
By default, constructor functions set the object prototype for the objects they create to the constructor’s prototype object.