{"id":10192,"date":"2016-04-08T10:23:59","date_gmt":"2016-04-08T15:23:59","guid":{"rendered":"http:\/\/jianmingli.com\/wp\/?p=10192"},"modified":"2018-01-16T15:58:46","modified_gmt":"2018-01-16T20:58:46","slug":"object-oriented-javascript","status":"publish","type":"post","link":"https:\/\/jianmingli.com\/wp\/?p=10192","title":{"rendered":"Object Oriented JavaScript"},"content":{"rendered":"<div class='toc wptoc'>\n<h2>Contents<\/h2>\n<ol class='toc-odd level-1'>\n\t<li>\n\t\t<a href=\"#Introduction\">Introduction<\/a>\n\t\t<ol class='toc-even level-2'>\n\t\t\t<li>\n\t\t\t\t<a href=\"#Variables\">Variables<\/a>\n\t\t\t<\/li>\n\t\t\t<li>\n\t\t\t\t<a href=\"#Variable_Scope\">Variable Scope<\/a>\n\t\t\t<\/li>\n\t\t\t<li>\n\t\t\t\t<a href=\"#Primitive_Data_Types\">Primitive Data Types<\/a>\n\t\t\t<\/li>\n\t\t\t<li>\n\t\t\t\t<a href=\"#Logical_Operators\">Logical Operators<\/a>\n\t\t\t<\/li>\n\t\t\t<li>\n\t\t\t\t<a href=\"#Comparisons\">Comparisons<\/a>\n\t\t\t<\/li>\n\t\t\t<li>\n\t\t\t\t<a href=\"#Arrays\">Arrays<\/a>\n\t\t\t<\/li>\n\t\t\t<li>\n\t\t\t\t<a href=\"#Conditions_and_Loops\">Conditions and Loops<\/a>\n\t\t\t<\/li>\n\t\t\t<li>\n\t\t\t\t<a href=\"#Functions\">Functions<\/a>\n\t\t\t\t<ol class='toc-odd level-3'>\n\t\t\t\t\t<li>\n\t\t\t\t\t\t<a href=\"#Private_Functions\">Private Functions<\/a>\n\t\t\t\t\t<\/li>\n\t\t\t\t\t<li>\n\t\t\t\t\t\t<a href=\"#Predefined_Functions\">Predefined Functions<\/a>\n\t\t\t\t\t<\/li>\n\t\t\t\t<\/ol>\n<\/ol>\n\t\t\t<li>\n\t\t\t\t<a href=\"#Objects\">Objects<\/a>\n\t\t\t\t<ol class='toc-even level-2'>\n\t\t\t\t\t<li>\n\t\t\t\t\t\t<a href=\"#Define_JavaScript_Objects\">Define JavaScript Objects<\/a>\n\t\t\t\t\t\t<ol class='toc-odd level-3'>\n\t\t\t\t\t\t\t<li>\n\t\t\t\t\t\t\t\t<a href=\"#Use_Object_Literal\">Use Object Literal<\/a>\n\t\t\t\t\t\t\t<\/li>\n\t\t\t\t\t\t\t<li>\n\t\t\t\t\t\t\t\t<a href=\"#Use_Constructor_Function_to_Define_Object\">Use Constructor Function to Define Object<\/a>\n\t\t\t\t\t\t\t<\/li>\n\t\t\t\t\t\t<\/ol>\n\t\t\t\t\t<li>\n\t\t\t\t\t\t<a href=\"#Access_Object_Properties\">Access Object Properties<\/a>\n\t\t\t\t\t\t<ol class='toc-odd level-3'>\n\t\t\t\t\t\t\t<li>\n\t\t\t\t\t\t\t\t<a href=\"#With_Square_Brackets\">With Square Brackets<\/a>\n\t\t\t\t\t\t\t<\/li>\n\t\t\t\t\t\t\t<li>\n\t\t\t\t\t\t\t\t<a href=\"#With_Dot_Notation\">With Dot Notation<\/a>\n\t\t\t\t\t\t\t<\/li>\n\t\t\t\t\t\t<\/ol>\n\t\t\t\t\t<li>\n\t\t\t\t\t\t<a href=\"#Built-in_Objects\">Built-in Objects<\/a>\n\t\t\t\t\t\t<ol class='toc-odd level-3'>\n\t\t\t\t\t\t\t<li>\n\t\t\t\t\t\t\t\t<a href=\"#Object\">Object<\/a>\n\t\t\t\t\t\t\t<\/li>\n\t\t\t\t\t\t\t<li>\n\t\t\t\t\t\t\t\t<a href=\"#Array\">Array<\/a>\n\t\t\t\t\t\t\t<\/li>\n\t\t\t\t\t\t\t<li>\n\t\t\t\t\t\t\t\t<a href=\"#Function\">Function<\/a>\n\t\t\t\t\t\t\t<\/li>\n\t\t\t\t\t\t<\/ol>\n<\/ol>\n\t\t\t\t\t<li>\n\t\t\t\t\t\t<a href=\"#Inheritance\">Inheritance<\/a>\n\t\t\t\t\t\t<ol class='toc-even level-2'>\n\t\t\t\t\t\t\t<li>\n\t\t\t\t\t\t\t\t<a href=\"#Example\">Example<\/a>\n\t\t\t\t\t\t\t<\/li>\n\t\t\t\t\t\t<\/ol>\n\t\t\t\t\t<li>\n\t\t\t\t\t\t<a href=\"#JavaScript_Namespaces\">JavaScript Namespaces<\/a>\n\t\t\t\t\t\t<ol class='toc-even level-2'>\n\t\t\t\t\t\t\t<li>\n\t\t\t\t\t\t\t\t<a href=\"#Overview\">Overview<\/a>\n\t\t\t\t\t\t\t<\/li>\n\t\t\t\t\t\t\t<li>\n\t\t\t\t\t\t\t\t<a href=\"#Create_Namespace\">Create Namespace<\/a>\n\t\t\t\t\t\t\t<\/li>\n\t\t\t\t\t\t\t<li>\n\t\t\t\t\t\t\t\t<a href=\"#Sub-namespace\">Sub-namespace<\/a>\n\t\t\t\t\t\t\t<\/li>\n\t\t\t\t\t\t\t<li>\n\t\t\t\t\t\t\t\t<a href=\"#Usage\">Usage<\/a>\n\t\t\t\t\t\t\t<\/li>\n\t\t\t\t\t\t<\/ol>\n\t\t\t\t\t<li>\n\t\t\t\t\t\t<a href=\"#JavaScript_Modules\">JavaScript Modules<\/a>\n\t\t\t\t\t\t<ol class='toc-even level-2'>\n\t\t\t\t\t\t\t<li>\n\t\t\t\t\t\t\t\t<a href=\"#Simple_Module\">Simple Module<\/a>\n\t\t\t\t\t\t\t<\/li>\n\t\t\t\t\t\t\t<li>\n\t\t\t\t\t\t\t\t<a href=\"#HidePublish_Module\">Hide\/Publish Module<\/a>\n\t\t\t\t\t\t\t<\/li>\n\t\t\t\t\t\t<\/ol>\n\t\t\t\t\t<li>\n\t\t\t\t\t\t<a href=\"#References\">References<\/a>\n\t\t\t\t\t<\/li>\n<\/ol>\n<\/ol>\n<\/div>\n<div class='wptoc-end'>&nbsp;<\/div>\n<span id=\"Introduction\"><h2>Introduction<\/h2><\/span>\n<p>* JavaScript uses class-less, prototype-oriented, or instance-based programming.<br \/>\n* JavaScript is case sensitive.<\/p>\n<span id=\"Variables\"><h3>Variables<\/h3><\/span>\n<p>* Examples:<\/p>\n<pre lang=\"javascript\">\r\n\/\/ Declare variable\r\nvar v1;\r\nvar V2 = 1;\r\nvar v3, v4 = 'Hello', V5;\r\n<\/pre>\n<span id=\"Variable_Scope\"><h3>Variable Scope<\/h3><\/span>\n<p>* JavaScript variables are defined in <em>function scope<\/em>, <strong>Not <\/strong>block scope:<br \/>\n&#8211; variable defined within a function (called a local variable) is <em>not<\/em> visible outside the function.<br \/>\n&#8211; variable defined in code blocks such as <em>if <\/em>or <em>for <\/em>blocks, it <em>is<\/em> visible outside the block.<br \/>\n* variables defined outside any function are called <em>global variables<\/em> (limit global variables to avoid naming collisions).<br \/>\n* variables declared without <em>var <\/em>is automatically assigned a global scope (avoid this!).<br \/>\n* Variable hoisting:<\/p>\n<pre lang=\"javascript\">\r\nvar v1 = 123;\r\nfunction f() {\r\n  alert(v1); \/\/ Undefined since v1 points to local v1.\r\n  var v1 = 1;\r\n  alert(v1);\r\n};\r\n<\/pre>\n<p>is hoisted to:<\/p>\n<pre lang=\"javascript\">\r\nvar v1 = 123;\r\nfunction f() {\r\n  var v1; \/\/ All local variables are hoisted to top of the function\r\n  alert(v1);\r\n  v1 = 1;\r\n  alert(v1);\r\n};\r\n<\/pre>\n<span id=\"Primitive_Data_Types\"><h3>Primitive Data Types<\/h3><\/span>\n<p>&#8211; Use <em>typeof <\/em>to find out about variable type<br \/>\n* Number<\/p>\n<pre lang=\"javascript\">\r\n\/\/ Number\r\nvar n1 = 1;\r\nvar n2 = 1.23;\r\nvar n3 = 0123; \/\/ octal\r\nvar n4 = 0xff; \/\/ hex\r\nvar n5 = ce+3; \/\/ exponent\r\nvar n6 = Infinity;\r\nvar n7 = NaN;\r\n<\/pre>\n<p>* String<\/p>\n<pre lang=\"javascript\">\r\nvar s1 = 'Hello world!';\r\n<\/pre>\n<p>* Boolean<\/p>\n<pre lang=\"javascript\">\r\nvar b1 = true, b2 = false;\r\n\/\/ Following all evaluate to false:\r\nfalse\r\n\"\"\r\nnull\r\nundefiend\r\n0\r\nNaN\r\n<\/pre>\n<p>* Undefined<br \/>\n* Null<\/p>\n<span id=\"Logical_Operators\"><h3>Logical Operators<\/h3><\/span>\n<p>* Not: !<br \/>\n* And: &#038;&#038;<br \/>\n* Or: ||<\/p>\n<span id=\"Comparisons\"><h3>Comparisons<\/h3><\/span>\n<p>* Loose equal: ==<br \/>\n* Strict equal: ===<br \/>\n* Not equal: !=<br \/>\n* Strict not equal: !==<br \/>\n* Others: <\/p>\n<pre lang=\"bash\">\r\n>\r\n>=\r\n<\r\n<=\r\n<\/pre>\n<span id=\"Arrays\"><h3>Arrays<\/h3><\/span>\n<p>* Zero index based.<br \/>\n* Elements can mix and match, e.g. numbers and strings.<\/p>\n<pre lang=\"javascript\">\r\n\/\/ Declare\r\nvar a1 = [];\r\nvar a2 = [1,2,3];\r\nvar a3 = ['array of arrays', a1,a2];\r\n\/\/ Assign element\r\na[0] = 1;\r\na[1] = 'hi';\r\n\r\n\/\/ Delete element\r\ndelete a2[3];\r\n<\/pre>\n<span id=\"Conditions_and_Loops\"><h3>Conditions and Loops<\/h3><\/span>\n<p>* if<\/p>\n<pre lang=\"javascript\">\r\n\/\/ if\r\nvar level = 9;\r\nvar s1;\r\nif (level > 5) {\r\n  s1 = 'hi';\r\n}else if (level >9){\r\n  s2 = 'hi yo';\r\n}else{\r\n  s3 = 'I'm not worthy!';\r\n}\r\n<\/pre>\n<p>* switch<\/p>\n<pre lang=\"javascript\">\r\nvar v1 = '1', s1 = '';\r\nswitch (v1) {\r\ncase 1:\r\n  s1 = 'One';\r\n  break;\r\ncase 2:\r\n  s1 = 'Two';\r\n  break;\r\ndefault:\r\n  s1 = 'Not sure';\r\n  break;\r\n}\r\n<\/pre>\n<p>* Loops<\/p>\n<pre lang=\"javascript\">\r\n\/\/ while\r\nvar i = 0;\r\nwhile (i < 10) {\r\n  i++;\r\n}\r\n\r\n\/\/ do while\r\ni = 0;\r\ndo {\r\n  i++;\r\n}while(i < 10);\r\n\r\n\/\/ for\r\nfor (var k = 0; k < 10; k++){\r\n  \/\/ do something\r\n}\r\n\r\n\/\/ for in\r\nvar a1 = ['a', 'b', 'c'];\r\nfor (var l in a1){\r\n  \/\/ do something\r\n}\r\n<\/pre>\n<span id=\"Functions\"><h3>Functions<\/h3><\/span>\n<p>* JavaScript functions always return values.<br \/>\n- Function returns <em>undefined <\/em>if it does not explicitly returning a value.<br \/>\n* Functions can be defined as either named functions or anonymous functions:<\/p>\n<pre lang=\"javascript\">\r\n\/\/ Named function\r\nfunction f1(){\r\n  alert('Named function. The name is f1');\r\n}\r\nvar v1 = f1(); \/\/ invoked f1\r\n\r\n\/\/ Anonymous function\r\nvar v2 = function (){\r\n  alert('Anonymous function');\r\n}\r\nv2(); \/\/ invoked anonymous function. Note the ()\r\n<\/pre>\n<p>* Functions are invoked with <strong><em>()<\/em><\/strong><br \/>\n* Function arguments are kept in special built-in variable named: <em>arguments<\/em><\/p>\n<pre lang=\"javascript\">\r\n\/\/ Implicitly defined special value: arguments\r\nfunction f2() {\r\n  var r = 0;\r\n  for (var i = 0; i < arguments.length; i++) {\r\n    r += arguments[i];\r\n  }\r\n  return r;\r\n}\r\n\r\nvar sum1 = f2(1,2); \/\/ sum1 = 3\r\nalert(sum1);\r\nvar sum2 = f2(1,2,3); \/\/ sum2 = 6\r\nalert(sum2);\r\n<\/pre>\n<p>* JavaScript functions are considered <em>data <\/em>which:<br \/>\n- contain code<br \/>\n- can be invoked<br \/>\n- can be passed as parameters<br \/>\n- can be returned from other functions<br \/>\n* Function can be assigned to a variable<\/p>\n<pre lang=\"javascript\">\r\n\/\/ Anonymous function assigned to a variable\r\nvar v1 = function (){\r\n  alert('hi');\r\n}\r\n<\/pre>\n<p>* Anonymous function can be:<br \/>\n- passed as a parameter to another function (as callback function).<\/p>\n<pre lang=\"javascript\">\r\n\/\/ Function that take function as parameters\r\nfunction sum1(a, b) {\r\n  return a() + b();\r\n}\r\n\r\n\/\/ Pass anonymous function as parameters\r\nvar p1 =  function(){\r\n    return 1;\r\n};\r\n\r\nvar r1 = sum1(p1,\r\n  \/\/ anonymous function as parameter on the fly\r\n  function(){\r\n    return 2;\r\n  }\r\n); \r\nalert(r1); \/\/ r1 = 3\r\n<\/pre>\n<p>* Anonymous functions are executed right away (as immediate function)<\/p>\n<pre lang=\"javascript\">\r\n(function(name){\r\n alert('Hello ' + name); \r\n})('world!');\r\n<\/pre>\n<span id=\"Private_Functions\"><h4>Private Functions<\/h4><\/span>\n<p>* Functions defined within a function are private to the parent function<\/p>\n<pre lang=\"javascript\">\r\nfunction outerf(name) {\r\n  function innerf(){\r\n    alert('Hello ' + name + ' from inner function!');\r\n  };\r\n  alert ('Hello ' + name + ' from outer function!');\r\n  innerf();\r\n}\r\n\r\nouterf('world');\r\n<\/pre>\n<p>* Private functions can be used to mimic Java getter\/setter methods:<\/p>\n<pre lang=\"javascript\">\r\n        function c1(p) {\r\n            var self = this;\r\n            self.getVal;\r\n            self.setVal;\r\n            (function () {\r\n                var name = p;\r\n\r\n                self.getVal = function () {\r\n                    return name;\r\n                };\r\n\r\n                self.setVal = function (v) {\r\n                    name = v;\r\n                };\r\n            }());\r\n        };\r\n\r\n        var v1 = new c1('hello');\r\n        alert(v1.getVal());\r\n        v1.setVal('world');\r\n        alert(v1.getVal());\r\n<\/pre>\n<span id=\"Predefined_Functions\"><h4>Predefined Functions<\/h4><\/span>\n<p>* <em>parseInt()<\/em>: string to int<\/p>\n<pre lang=\"javascript\">\r\nvar s1 = '123';\r\nvar n1 = parseInt(s1) \/\/ n1 = 123\r\n\r\nvar n2 = parseInt('FF', 16); \/\/ n2 = 255\r\n\r\nvar n3 = parseInt('0377', 8); \/\/ n3 = 255\r\nvar n4 = parseInt('0x377'); \/\/ n4 = 887\r\n<\/pre>\n<p>* <em>parseFloat()<\/em>: string to float<\/p>\n<pre lang=\"javascript\">\r\nvar s2 = '1.23';\r\nvar n2 = parseFloat(s2) \/\/ n2 = 1.23\r\n<\/pre>\n<p>* <em>isNaN()<\/em><br \/>\n* <em>isFinite()<\/em><br \/>\n* <em>encodeURI()<\/em>: encode full URI<br \/>\n* <em>decodeURI()<\/em><br \/>\n* <em>encodeURIcomponent()<\/em>: encode partial URI<br \/>\n* <em>decodeURIComponent()<\/em><\/p>\n<pre lang=\"javascript\">\r\nvar url1 = 'http:\/\/my.com\/hello world';\r\nvar e1 = encodeURIComponent(url1); \/\/ e1 = 'http:\/\/my.com\/hello%20world'\r\n<\/pre>\n<p>* <em>eval()<\/em>: do not use<br \/>\n* <em>alert()<\/em><\/p>\n<span id=\"Objects\"><h2>Objects<\/h2><\/span>\n<p>* JavaScript object contains:<br \/>\n- properties (name value pairs)<br \/>\n- methods<br \/>\n* Use <strong><em>this <\/em><\/strong> keyword to access properties within object<br \/>\n* JavaScript objects are passed <em>by reference<\/em>.<br \/>\n- also equal by reference like Java<\/p>\n<span id=\"Define_JavaScript_Objects\"><h3>Define JavaScript Objects<\/h3><\/span>\n<span id=\"Use_Object_Literal\"><h4>Use Object Literal<\/h4><\/span>\n<p>* Define a simple object just like Java map or C# dictionary<\/p>\n<pre lang=\"javascript\">\r\n\/\/ Define an object\r\nvar Book1 = {\r\n\t\ttitle: '', \/\/ property\r\n\t\tauthor: { \/\/ nested object\r\n\t\t\t\tfirstname: '',\r\n\t\t\t\tlastname: ''\r\n\t\t},\r\n\t\tdescription: '',\r\n\t\tsayhi: function(name) { \/\/ method\r\n\t\t\t\treturn 'Hello ' + name + ' from ' + this.author.firstname;\r\n\t\t}\r\n};\r\n\r\n\/\/ Set property values\r\nBook1.title = 'Book One';\r\nBook1.author.firstname = 'John';\r\nBook1.author.lastname = 'Doe';\r\nBook1.description = 'This is book one.';\r\n\r\n\/\/ Access object\r\nBook1.title; \/\/ Dot notation, title has to be an explicit string. It cannot be a variable\r\nBook1['title']; \/\/ Property notation. Property name can be a variable\r\n\r\nBook1.author.firstname; \/\/ Again, both author and firstname have to be explicit strings\r\nBook1['author']['firstname'];\r\n\r\nBook1.sayhi('world');\r\n<\/pre>\n<span id=\"Use_Constructor_Function_to_Define_Object\"><h4>Use Constructor Function to Define Object<\/h4><\/span>\n<p>* Constructor function name is capitalized by convention.<br \/>\n* Use <strong><em>new <\/em><\/strong>keyword to instantiate constructor object.<br \/>\n* Special property named <em>constructor <\/em> holds the reference to constructor function used to construct the object.<br \/>\n* Once constructed, <em>this<\/em> object points to the newly construct object.<br \/>\n- best practice: use <em>var self = this;<\/em> to remember constructed object.<br \/>\n- See <a href=\"http:\/\/javascriptissexy.com\/understand-javascripts-this-with-clarity-and-master-it\/\">this <\/a>article for more details on <em>this <\/em>object<\/p>\n<pre lang=\"javascript\">\r\nfunction Author(firstname, lastname) {\r\n\t\tvar self = this;\r\n\t\tself.firstname = firstname;\r\n\t\tself.lastname = lastname;\r\n\t\tself.fullname = function () {\r\n\t\t\t\treturn self.firstname + ' ' + self.lastname;\r\n\t\t};\r\n};\r\n\r\nfunction Book(author,title){\r\n\t\tvar self = this;\r\n\r\n\t\tself.title = title;\r\n\t\tself.author = author;\r\n\t\tself.sayhi = function () {\r\n\t\t\t\treturn 'Hello from ' + self.author.fullname();\r\n\t\t};\r\n};\r\n\r\nvar author1 = new Author('john', 'doe');\r\nauthor1.constructor; \/\/ Show constructor function\r\nauthor1 instanceof Author; \/\/ Test instance of. Returns true\r\n\r\nvar book1 = new Book(author1, 'Book One');\r\nbook1.sayhi(); \/\/ Hello from john doe\r\n\r\n\/\/ Pass by reference\r\nauthor1.firstname = 'jane';\r\nbook1.sayhi(); \/\/ Hello from jane doe\r\n<\/pre>\n<p>* More examples:<\/p>\n<pre lang=\"javascript\">\r\nfunction JustName(name) {\r\n\tvar self = this; \/\/ Remember this object\r\n\tself.name = name;\r\n};\r\n\r\nJustName.prototype.title = \"Mr.\";\r\nJustName.prototype.hi = function() {\r\n\tvar self = this;\r\n\treturn \"Hello \" + this.title + \" \" + this.name; \/\/ Note use 'this' instead of 'self' object here!\r\n}\r\n\r\nvar name1 = new JustName('Name1');\r\nname1.hi(); \/\/ Hello Mr. Name1\r\n\r\nvar name2 = new JustName('Name2');\r\nname2.hi(); \/\/ Hello Mr. Name2\r\n\r\n\/\/ Switch this object to name2 with call or apply functions\r\n\/\/ Reads name1.hi function called by name2 object\r\nname1.hi.call(name2); \/\/ Hello Mr. Name2\r\nname1.hi.apply(name2); \/\/ Hello Mr. Name2\r\n\r\n\/\/ Switch this object to name2 with bind function:\r\nname1.hi.bind(name2)(); \/\/ Hello Mr. Name2\r\n<\/pre>\n<span id=\"Access_Object_Properties\"><h3>Access Object Properties<\/h3><\/span>\n<p>* In JavaScript, all property keys are strings!<\/p>\n<span id=\"With_Square_Brackets\"><h4>With Square Brackets<\/h4><\/span>\n<p>* Evaluates the first complete expression with square brackets in a statement<br \/>\n* Runs toString() on it to convert it into a string<br \/>\n* And then uses that value for the next bracket expression<br \/>\n* Untill it runs out of bracket expressions.<\/p>\n<span id=\"With_Dot_Notation\"><h4>With Dot Notation<\/h4><\/span>\n<p>* Can only be used to access explicit key name of a property<br \/>\n* Can NOT used non-string value, such as variables or numbers, in the dot notation<\/p>\n<span id=\"Built-in_Objects\"><h3>Built-in Objects<\/h3><\/span>\n<p>* Data wrapper objects:<br \/>\n- Object<br \/>\n- Array<br \/>\n- Function<br \/>\n- Boolean<br \/>\n- Number<br \/>\n- String<br \/>\n* Utility objects<br \/>\n- Math<br \/>\n- Date<br \/>\n- RegEXP<br \/>\n* Error objects<br \/>\n- Error<\/p>\n<span id=\"Object\"><h4>Object<\/h4><\/span>\n<p>* Methods:<\/p>\n<pre lang=\"javascript\">\r\nvar o = new Object();\r\no.constructor;\r\no.toString()\r\no.valueOf()\r\n<\/pre>\n<span id=\"Array\"><h4>Array<\/h4><\/span>\n<p>* Array properties and methods:<\/p>\n<pre lang=\"javascript\">\r\nvar a = [1, 2, 'three'];\r\nalert(a); \/\/ 1,2,three\r\nalert(a.length); \/\/ 3\r\n\r\na.push('four');\r\nalert(a); \/\/ 1,2,three,four\r\n\r\na.sort();\r\nalert(a); \/\/ 1,2,four,three\r\n\r\na.join(', '); \/\/ returns comma delimited string\r\nalert(a); \/\/ 1,2,four,three\r\n\r\nvar b = a.slice(1, 3);\r\nalert(a); \/\/ 1,2,four,three\r\nalert(b); \/\/ 2,four\r\na.splice(1, 3);\r\nalert(a); \/\/ 1\r\n<\/pre>\n<span id=\"Function\"><h4>Function<\/h4><\/span>\n<p>* Properties:<\/p>\n<pre lang=\"javascript\">\r\nfunction F(name) {\r\n\t\treturn 'hi ' + name;\r\n}\r\nvar f1 = new F();\r\nF.constructor; \/\/ constructor property\r\nF.length; \/\/ Length of input parameters, i.e. 1\r\n<\/pre>\n<p>* Prototype property<br \/>\n- every function has a <em>prototype <\/em>property which contains an object<br \/>\n- prototype chain is <em>live<\/em> (meaning changes to prototype affects all constructors)<br \/>\n- properties and methods can be added to function via prototype<br \/>\n- properties and methods are searched up the prototype chain<br \/>\n- <em>reset <\/em>constructor when you overwrite the prototype as in inheritance<\/p>\n<pre lang=\"javascript\">\r\nfunction F1() {\r\n\t\tvar self = this;\r\n\t\tself.name = 'John';\r\n\t\tself.say = function () {\r\n\t\t\t\treturn 'I\\'m ' + self.name;\r\n\t\t};\r\n};\r\n\r\n\/\/ Add property and methods to F1 function via prototype\r\nF1.prototype.title = 'Mr.';\r\nF1.prototype.properHi = function () {\r\n\t\treturn 'Hi ' + this.title + ' I\\'m ' + this.name;\r\n};\r\n\r\nvar f3 = new F1();\r\nalert(f3.properHi()); \/\/ Hi Mr. I'm John\r\n\r\n\/\/ Reset constructor\r\nF1.prototype.constructor = F1; \/\/ Used in inheritance\r\n<\/pre>\n<p>* Methods:<br \/>\n- <em>call<\/em>: used to <em>\"borrow\"<\/em> a method from another function, e.g.:<\/p>\n<pre lang=\"javascript\">\r\nvar f1 = {\r\n\t\tname: 'john',\r\n\t\tsay: function (who) {\r\n\t\t\t\treturn 'hi ' + who + ' i\\'m ' + this.name;\r\n\t\t}\r\n};\r\nalert(f1.say('world')); \/\/ hi world i'm john\r\n\r\nvar f2 = {\r\n\t\tname: 'jane'\r\n};\r\n\/\/ Borrow f1's say method, i.e. f1.say method is called by f2 with parameter of 'Mars':\r\nalert(f1.say.call(f2, 'Mars')); \/\/ hi Mars i'm jane\r\n<\/pre>\n<p>- <em>apply<\/em>: similar to call except all parameters are passed in an array<\/p>\n<span id=\"Inheritance\"><h2>Inheritance<\/h2><\/span>\n<p>* JavaScript uses function prototype to implement inheritance.<\/p>\n<span id=\"Example\"><h3>Example<\/h3><\/span>\n<pre lang=\"javascript\">\r\n\/\/ A helper function to extend parent constructor\r\nfunction extend(Child, Parent) {\r\n    \/\/ Use a dummy function to break prototype chain\r\n    \/\/ so changes from child won't affect parent's\r\n    var F = function () { };\r\n    F.prototype = Parent.prototype;\r\n    Child.prototype = new F();\r\n\r\n    \/\/ Reset constructor\r\n    Child.prototype.constructor = Child;\r\n\r\n    \/\/ Remember parent (super) prototype \r\n    \/\/ so child can access parent functions\r\n    Child.uber = Parent.prototype;\r\n};\r\n\r\n\/\/ Define Shape parent function\r\nfunction Shape() { };\r\n\/\/ Use prototype to define a common name property\r\nShape.prototype.name = 'Shape';\r\n\/\/ Use prototype to define a common toString property\r\nShape.prototype.toString = function () {\r\n    return this.constructor.uber\r\n        ? this.constructor.uber.toString() + ', ' + this.name\r\n        : this.name;\r\n};\r\n\r\n\/\/ Define TwoDShape child function\r\nfunction TwoDShape() { };\r\n\/\/ which extends from Shape parent function\r\nextend(TwoDShape, Shape);\r\n\/\/ Override name property\r\nTwoDShape.prototype.name = 'Two D Shape';\r\n\r\n\/\/ Define Triangle child function\r\n\/\/ It has its own properties\r\nfunction Triangle(side, height) {\r\n    this.side = side;\r\n    this.height = height;\r\n};\r\n\/\/ Triangle function extends from TwoDShape\r\nextend(Triangle, TwoDShape);\r\n\/\/ Override the name property\r\nTriangle.prototype.name = \"Triangle\";\r\n\/\/ It can implement its own method\r\nTriangle.prototype.getArea = function () {\r\n    return (this.side * this.height) \/ 2;\r\n};\r\n\r\n\/\/ Usage\r\nvar tri1 = new Triangle(10, 10);\r\nalert('triangle name: ' + tri1.name); \/\/ Triangle\r\nalert('triangle area: ' + tri1.getArea()); \/\/ 50\r\n<\/pre>\n<span id=\"JavaScript_Namespaces\"><h2>JavaScript Namespaces<\/h2><\/span>\n<span id=\"Overview\"><h3>Overview<\/h3><\/span>\n<p>* JavaScript namespace is just a POJO (plain old JavaScript <em>object<\/em>) used as a container\/qualifier for all:<br \/>\n- variables<br \/>\n- methods<br \/>\n- functions<br \/>\n* No different to other JavaScript functions<br \/>\n* Used to avoid name conflicts<br \/>\n* By convention, namespaces are all caps?<\/p>\n<span id=\"Create_Namespace\"><h3>Create Namespace<\/h3><\/span>\n<p>* Root namespace:<\/p>\n<pre lang=\"javascript\">\r\nvar MYAPP = MYAPP || {};\r\n<\/pre>\n<p>* Equivalent to:<\/p>\n<pre lang=\"javascript\">\r\nif (typeof MYAPP == \"undefined\") {\r\n  var MYAPP = MYAPP {};\r\n}\r\n<\/pre>\n<p>Both:<br \/>\n- check whether namespace is already defined<br \/>\n- if yes, use the existing global object<br \/>\n- if no, create an empty global object<\/p>\n<span id=\"Sub-namespace\"><h3>Sub-namespace<\/h3><\/span>\n<pre lang=\"javascript\">\r\nvar MYAPP = MYAPP || {},\r\n    MYAPP.event = MYAPP.event || {},\r\n    MYAPP.event.mouse = MYAPP.event.mouse || {};\r\n<\/pre>\n<p>* Or<\/p>\n<pre lang=\"javascript\">\r\nvar MYAPP = MYAPP || {};\r\nMYAPP = {\r\n  MODEL: {\r\n    product: function(price) {\r\n      this.price = price;\r\n      this.getPrice = function () {\r\n        return this.price;\r\n      };\r\n    }\r\n  },\r\n  LOGIC: {\r\n    calculateVat: function(base) {\r\n      return base * 1.21;\r\n    },\r\n    calculate: function() {\r\n      var p = new MYAPP.MODEL.product(100);\r\n      alert9this.calculateVat(p.getPrice());\r\n    }\r\n  }\r\n}\r\n<\/pre>\n<span id=\"Usage\"><h3>Usage<\/h3><\/span>\n<p>* Think of namespaces as name qualifiers<br \/>\n* In the following example, we define a namespace named <em>MYAPP<\/em> and qualify all related variables, functions, classes, etc. with it.<\/p>\n<pre lang=\"javascript\">\r\nvar MYAPP = MYAPP || {};\r\nMYAPP.Person = function(name) {\r\n  this.name = name;\r\n  if (this.name != null) {\r\n    console.log(\"Person object named: \" + this.name + \" has been instantiated.\");\r\n    this.aliasName = name;\r\n  } else {\r\n    console.log(\"Person object has been instantiated.\");\r\n    this.aliasName = \"unknown\";\r\n  }\r\n};\r\n\r\nMYAPP.Person.prototype.sayHello = function() {\r\n    console.log(\"Hello \" + this.aliasName);\r\n};\r\n\r\nvar p1 = new MYAPP.Person(\"John\");\r\nconsole.log(\"p1 aliasName: \" + p1.aliasName);\r\np1.sayHello();\r\n<\/pre>\n<span id=\"JavaScript_Modules\"><h2>JavaScript Modules<\/h2><\/span>\n<span id=\"Simple_Module\"><h3>Simple Module<\/h3><\/span>\n<pre lang=\"javascript\">\r\n\/\/ Only expose MyModule in global scope\r\nvar MyModule = (function (){\r\n  var _firstName = \"John\";\r\n  var _lastName = \"Doe\";\r\n  \r\n  \/* Private function *\/\r\n  function fullName() {\r\n    return _firstName + \" \" + _lastName;\r\n  }\r\n  \r\n  function sayHi(name) {\r\n    var tmpName = name || \"Stranger\";\r\n    alert(\"Hi \" + tmpName + \" from \" + fullName());\r\n  }\r\n  \r\n  \/* Public function *\/\r\n  return {\r\n    sayHi: sayHi\r\n  };\r\n})();\r\n\r\n\/\/ Use My Module:\r\nMyModule.sayHi(\"Jane\");\r\n<\/pre>\n<span id=\"HidePublish_Module\"><h3>Hide\/Publish Module<\/h3><\/span>\n<pre lang=\"javascript\">\r\n\/\/ Hide MyModule from global scope\r\n(function(win, doc){\r\n\tvar MyModule = (function (){\r\n\t\tvar _firstName = \"John\",\r\n\t\t_lastName = \"Doe\";\r\n\t\t\r\n\t\t\/* Private function *\/\r\n\t\tfunction fullName() {\r\n\t\t\treturn _firstName + \" \" + _lastName;\r\n\t\t}\r\n\t\t\r\n\t\tfunction sayHi(name) {\r\n\t\t\tvar tmpName = name || \"Stranger\";\r\n\t\t\talert(\"Hi \" + tmpName + \" from \" + fullName());\r\n\t\t}\r\n\t\t\r\n\t\t\/* Public function *\/\r\n\t\treturn {\r\n\t\t\tsayHi: sayHi\r\n\t\t};\r\n\r\n\t\t\/\/ Expose MyModule as public module win.MyModule\r\n\t\tif (!win.MyModule) win.MyModule = MyModule;\r\n\t})(window, document);\r\n})();\r\n\r\n\/\/ Use My Module:\r\nwindow.MyModule.sayHi(\"Jane\");\r\n<\/pre>\n<span id=\"References\"><h2>References<\/h2><\/span>\n<p>* <a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/JavaScript\/Introduction_to_Object-Oriented_JavaScript\">Introduction to Object-Oriented JavaScript<\/a><br \/>\n* <a href=\"http:\/\/www.kenneth-truyers.net\/2013\/04\/27\/javascript-namespaces-and-modules\/\">JavaScript Namespaces and Modules<\/a><br \/>\n* <a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/JavaScript\/Reference\/Global_Objects\">Standard built-in JavaScript objects<br \/>\n<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Introduction * JavaScript uses class-less, prototype-oriented, or instance-based programming. * JavaScript is case sensitive. Variables * Examples: \/\/ Declare variable var v1; var V2 = 1; var v3, v4 = &#8216;Hello&#8217;, V5; Variable Scope * JavaScript variables are defined in &hellip; <a href=\"https:\/\/jianmingli.com\/wp\/?p=10192\">Continue reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_exactmetrics_skip_tracking":false,"_exactmetrics_sitenote_active":false,"_exactmetrics_sitenote_note":"","_exactmetrics_sitenote_category":0,"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":true,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":false,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2}},"categories":[18],"tags":[496,686],"class_list":["post-10192","post","type-post","status-publish","format-standard","hentry","category-javascript","tag-javascript-2","tag-oop"],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"jetpack_shortlink":"https:\/\/wp.me\/p8cRUO-2Eo","_links":{"self":[{"href":"https:\/\/jianmingli.com\/wp\/index.php?rest_route=\/wp\/v2\/posts\/10192","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/jianmingli.com\/wp\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/jianmingli.com\/wp\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/jianmingli.com\/wp\/index.php?rest_route=\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/jianmingli.com\/wp\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=10192"}],"version-history":[{"count":17,"href":"https:\/\/jianmingli.com\/wp\/index.php?rest_route=\/wp\/v2\/posts\/10192\/revisions"}],"predecessor-version":[{"id":12108,"href":"https:\/\/jianmingli.com\/wp\/index.php?rest_route=\/wp\/v2\/posts\/10192\/revisions\/12108"}],"wp:attachment":[{"href":"https:\/\/jianmingli.com\/wp\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=10192"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/jianmingli.com\/wp\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=10192"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/jianmingli.com\/wp\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=10192"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}