-
-
Save csalzman/1e02380398cc8f4a5a43c4d630cd09b1 to your computer and use it in GitHub Desktop.
<script type="text/javascript"> | |
/* | |
Walking through this page as a tutorial on how Javascripts object model works: | |
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Details_of_the_Object_Model#Class-Based_vs._Prototype-Based_Languages | |
*/ | |
//Function for Employee creates a constructor for Employee objects | |
function Employee() { | |
this.name = ""; | |
this.dept = "General"; | |
this.title = ""; | |
} | |
//Manager is going to inherit from Employee and add a reports property | |
function Manager() { | |
Employee.call(this); | |
this.reports = []; | |
//Setting the title property that Employee setup | |
this.title = "Manager"; | |
} | |
//***I am unsure what this does.*** | |
Manager.prototype = Object.create(Employee.prototype); | |
//Create an instance of an object using the Manager constructor | |
var mintedManager = new Manager(); | |
document.write(mintedManager.title); | |
</script> |
Alternatively you could do something like:
function Employee() {
this.name = "";
this.dept = "General";
this.title = "";
}
Employee.prototype.company = 'Acme';
function Manager() {
this.reports = [];
this.title = "Manager";
}
Manager.prototype = new Employee();
var mintedManager = new Manager();
document.write(mintedManager.company);
But this is slightly different, it sets the new Employee
object as the actual prototype.
I think I can see reasons to mix new
and object.create
but I think it's a bit confusing to do that. Generally I like to use one or the other, I prefer Object.create and object literals. For example you can have a similar prototype chain with this code:
var employeeProto = {
name: "",
dept: "General",
title: ""
};
function newManager() {
var manager = Object.create(employeeProto);
manager.title = "Manager";
return manager;
}
var mintedManager = newManager();
document.write(mintedManager.dept);
@hypomodern I thanked you on twitter too, but publicly (on this gist that will probably die someday in a gist purge) thank you!
@keller, thanks! Your object literal example makes a lot more sense to me given how its used in this example. It's helpful to understand the options!
"It feels to me like it's trying to trick devs into thinking it's like classical inheritance, which they successfully do trick devs into being confused" I've really really been feeling this as I'm learning about this. I'd actually started looking into it after reading a bit about classes in es6 and wondering what was making them work.
I love and hate JS prototype inheritance. I think it's super cool, but a mess of an api. It feels to me like it's trying to trick devs into thinking it's like classical inheritance, which they successfully do trick devs into being confused. I think the biggest (recent) mistake was to add es6 classes, and hiding proto inheritance more, rather than adding a better proto inheritance api.
@hypomodern is correct that
Employee.call(this)
is used to "call" theEmployee()
"function" but it's a little confusing becauseEmployee
isn't a normal function. It's a special JS constructor function so in this case Employee.call(this) is used to chain constructors. So whennew Manager()
is called, it also runs theEmployee()
constructor function, sending it'sthis
and thus settingthis.name
,this.dept
, andthis.title
for the new manager object.Line 23 is creating the new manager object's prototype to be a newly created object with it's prototype the same as the
Employee
prototype, which I think by default isObject
. So your code really doesn't need that line since setting a prototype is basically empty. @hypomodern is correct that setting a prototype forEmployee
will allow that line to be useful.