{"id":293,"date":"2012-01-04T06:40:04","date_gmt":"2012-01-04T06:40:04","guid":{"rendered":"http:\/\/www.thespidercloud.com\/?p=77"},"modified":"2012-01-04T06:40:04","modified_gmt":"2012-01-04T06:40:04","slug":"all-about-objects","status":"publish","type":"post","link":"https:\/\/frowningbear.com\/codebase\/2012\/01\/04\/all-about-objects\/","title":{"rendered":"All about Objects"},"content":{"rendered":"<p>Trying to sum up the essentials of objects in javascript as succinctly as possible but with enough examples to illustrate the concepts clearly.<\/p>\n<p>I will add more and update this page as it occurs to me until I feel satisfied that its as complete and helpful as possible.<\/p>\n<p><!--more--><\/p>\n<h2>Creating Objects<\/h2>\n<pre class=\"lang:default decode:true \" title=\"Object creation\">\/\/ the traditional way using the Object constructor\nvar myObj = new Object();\n\n\/\/now add your properties and methods\nmyObj.str = \"Hello\";\nmyObj.num = 5;\nmyObj.arr = [1, 2, 3, 4, 5];\nmyObj.subObject = {title: \"Psycho\", year: \"1960\"};\nmyObj.fn = function() { alert( this.str ) };\n\n\n\/\/object literal\nvar myObj = {\n\tstr: \"Hello\",\n\tnum: 5,\n\tarr: [1, 2, 3, 4, 5],\n\tsubObject: {title: \"Psycho\", year: \"1960\"},\n\tfn: function() { alert( this.str ) }\n};\n\n\n\/\/ Defining your own constructor function to create\n\/\/ a custom object type\nfunction CustomObj(str, num, arr, sub, fn) {\n\tthis.str = str;\n\tthis.num = num;\n\tthis.arr = arr;\n\tthis.subObject = sub;\n\tthis.fn = fn;\n}\n\n\/\/ then create an instance of Obj withe the new keyword and \n\/\/ pass in your arguments\nvar myObj = new CustomObj(\"Hello\", 5, [1,2,3], {name: \"Joe\"}, \nfunction() {alert(this.str)});\n\n<\/pre>\n<h2>Diving deeper into the sea of Objects.<\/h2>\n<pre class=\"lang:default decode:true \" title=\"Objects\">var Person = function (firstName) {\n  this.firstName = firstName;\n};\n\nvar Cat = function (n, s) {\n  this.name = n;\n  this.sex = s;\n};\n\nPerson.prototype.sayHello = function() {\n  console.log(\"Hello, I'm \" + this.firstName);\n};\n\nvar person1 = new Person(\"Alice\");\nvar person2 = new Person(\"Bob\");\nvar person3 = new Person(\"John\");\n\nperson2.prototype = {objname : \"person2 prototype\"};\n\nperson3.prototype = new Cat(\"Fluffy\", \"female\");\n\nperson1.sayHello(); \/\/ logs \"Hello, I'm Alice\"\n\nperson2.sayHello(); \/\/ logs \"Hello, I'm Bob\"\n\nconsole.log(person1.firstName); \/\/ Alice\n\nconsole.log(person1.prototype); \/\/ undefined\n\nconsole.log(Person.prototype); \/\/ shows the object with its sayHello function\n\nconsole.log(Object.getPrototypeOf(person1)); \/\/ same as above\n\nconsole.log(Person); \/\/ shows the constructor function\n\nconsole.log(Person.prototype.sayHello); \/\/ show the function\n\nPerson.prototype.sayHello(); \/\/ call the function\n\nconsole.log(person1.constructor); \/\/ shows the constructor function\n\nconsole.log(person2.prototype); \/\/ shows the object with its objname prop\n\nconsole.log(Object.getPrototypeOf(person2));\n\nconsole.log(person3.prototype); \/\/ shows the object with its two props\n\nconsole.log(Object.getPrototypeOf(person3)); \/\/ the prototype object of person3 \nis an instance of Person\n<\/pre>\n<p>prototype and Object.getPrototypeOf<\/p>\n<p>JavaScript is a bit confusing for developers coming from Java or C++, as it&#8217;s all dynamic, all runtime, and it has no classes at all. It&#8217;s all just instances (objects). Even the &#8220;classes&#8221; we simulate are just a function object.<\/p>\n<p>You probably already noticed that our function A has a special property called prototype. This special property works with the JavaScript new operator. The reference to the prototype object is copied to the internal [[Prototype]] property of the new instance. For example, when you do var a1 = new A(), JavaScript (after creating the object in memory and before running function A() with this defined to it) sets a1.[[Prototype]] = A.prototype. When you then access properties of the instance, JavaScript first checks whether they exist on that object directly, and if not, it looks in [[Prototype]]. This means that all the stuff you define in prototype is effectively shared by all instances, and you can even later change parts of prototype and have the changes appear in all existing instances, if you wanted to.<\/p>\n<p>If, in the example above, you do var a1 = new A(); var a2 = new A(); then a1.doSomething would actually refer to Object.getPrototypeOf(a1).doSomething, which is the same as the A.prototype.doSomething you defined, i.e. Object.getPrototypeOf(a1).doSomething == Object.getPrototypeOf(a2).doSomething == A.prototype.doSomething.<\/p>\n<p>In short, prototype is for types, while Object.getPrototypeOf() is the same for instances.<\/p>\n<p>[[Prototype]] is looked at recursively, i.e. a1.doSomething, Object.getPrototypeOf(a1).doSomething, Object.getPrototypeOf(Object.getPrototypeOf(a1)).doSomething etc., until it&#8217;s found or Object.getPrototypeOf returns null.<\/p>\n<p>So, when you call<\/p>\n<p>var o = new Foo();<\/p>\n<p>JavaScript actually just does<\/p>\n<p>var o = new Object();<br \/>\no.[[Prototype]] = Foo.prototype;<br \/>\nFoo.call(o);<\/p>\n<p>(or something like that) and when you later do<\/p>\n<p>o.someProp;<\/p>\n<p>it checks whether o has a property someProp. If not it checks Object.getPrototypeOf(o).someProp and if that doesn&#8217;t exist it checks Object.getPrototypeOf(Object.getPrototypeOf(o)).someProp and so on.<\/p>\n<p>\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>\/\/\/\/\/\/\/\/\/\/\/\/<br \/>\nvar o = {a: 1, b: 2};<\/p>\n<p>o.__proto__ === Object.prototype; \/\/ true<br \/>\nObject.getPrototypeOf(o) === Object.prototype; \/\/ true<br \/>\nObject.getPrototypeOf(o) === Array.prototype \/\/ false<br \/>\no.hasOwnProperty(&#8216;a&#8217;); \/\/ true<br \/>\no.constructor \/\/ function Object()<br \/>\no.hasOwnProperty(constructor) \/\/ false<\/p>\n<p>o.__proto__.__proto__; \/\/ null <\/p>\n<p>\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/<\/p>\n<p>var o = {a: 1, b: 2};<br \/>\nvar m = {c: 3, d: 4};<br \/>\no.__proto__ = m;<\/p>\n<p>o.__proto__ === m; \/\/ true<\/p>\n<p>m.__proto__ === Object.prototype \/\/ true<\/p>\n<p>o.__proto__ === Object.prototype \/\/ false<\/p>\n<p>o.__proto__.__proto__ === Object.prototype \/\/ true<\/p>\n<p>\/\/\/\/\/\/\/\/\/\/\/\/\/\/<\/p>\n<p>var myfunc = function() {};<\/p>\n<p>myfunc.name \/\/ &#8220;myfunc&#8221;<\/p>\n<p>myfunc.length \/\/ 0<\/p>\n<p>Function.prototype.constructor === Function \/\/ true<\/p>\n<p>\/\/ Functions have a prototype property but objects don&#8217;t<br \/>\n\/\/ However both have actual [[Prototype]]s since both are objects<\/p>\n<p>myfunc.constructor \/\/ function Function()<\/p>\n<p>myfunc.hasOwnProperty(&#8216;constructor&#8217;) \/\/ false<\/p>\n<p>myfunc.__proto__.hasOwnProperty(&#8216;constructor&#8217;) \/\/ true<\/p>\n<p>\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/<\/p>\n<p>function A () {<br \/>\n\tthis.aprop = &#8220;a&#8221;;<br \/>\n}<\/p>\n<p>function B () {<br \/>\n\tA.call(this)<br \/>\n\tthis.bprop = &#8220;b&#8221;;<br \/>\n}<\/p>\n<p>var myb = new B();<\/p>\n<p>myb instanceof B; \/\/ true<\/p>\n<p>myb instanceof A; \/\/ false <\/p>\n<p>myb.aprop \/\/ a<\/p>\n<p>myb.hasOwnProperty(&#8216;aprop&#8217;); \/\/ true<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Trying to sum up the essentials of objects in javascript as succinctly as possible but with enough examples to illustrate the concepts clearly. I will add more and update this page as it occurs to me until I feel satisfied that its as complete and helpful as possible.<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[3],"tags":[],"class_list":["post-293","post","type-post","status-publish","format-standard","hentry","category-javascript"],"jetpack_sharing_enabled":true,"jetpack_featured_media_url":"","_links":{"self":[{"href":"https:\/\/frowningbear.com\/codebase\/wp-json\/wp\/v2\/posts\/293","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/frowningbear.com\/codebase\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/frowningbear.com\/codebase\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/frowningbear.com\/codebase\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/frowningbear.com\/codebase\/wp-json\/wp\/v2\/comments?post=293"}],"version-history":[{"count":0,"href":"https:\/\/frowningbear.com\/codebase\/wp-json\/wp\/v2\/posts\/293\/revisions"}],"wp:attachment":[{"href":"https:\/\/frowningbear.com\/codebase\/wp-json\/wp\/v2\/media?parent=293"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/frowningbear.com\/codebase\/wp-json\/wp\/v2\/categories?post=293"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/frowningbear.com\/codebase\/wp-json\/wp\/v2\/tags?post=293"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}