JavaScript - Help Understanding Inheritance And Nested Objects (non-dom Related)
I posted this once, but it disappeared, and I have no notifications that I did anything wrong. I read the rules before posting and wasn't breaking any so I am not sure why it disappeared but here goes again.
I am trying to learn Javascript (particularly OOP) from a series of screencasts by Douglas Crockford. I have developed a theoretical "game" to build to illustrate it to myself better, and learn by example. I must be misunderstanding how inheritance works, because my code is not producing the results I thought it would. Here is what I have, followed by an explanation of my understanding. Code: $(function() { function object(o) { function Funct() {} Funct.prototype = o; return new Funct(); } soldier = { pointsCost: 0, movement: "1 Infantry Block", validTargets: {}, weapons: { "Main Weapon": { "Weapon Type": "M4 Carbine", "Fire Range": 12 }, "Secondary Weapon": { "Weapon Type": "JCP .45", "Fire Range": 3 } } }; var rifleman = object(soldier); rifleman.pointsCost += 10; rifleman.validTargets.target1 = "Infantry" rifleman.weapons["Secondary Weapon"]["Weapon Type"] = ""; rifleman.weapons["Secondary Weapon"]["Fire Range"] = ""; var heavyGunner = object(soldier); heavyGunner.pointsCost += 20; heavyGunner.validTargets.target1 = "Infantry"; heavyGunner.validTargets.target2 = "Light Armor"; heavyGunner.weapons["Main Weapon"]["Weapon Type"] = "SAW M249"; heavyGunner.weapons["Main Weapon"]["Fire Range"] = 12; heavyGunner.weapons["Secondary Weapon"]["Weapon Type"] = ""; heavyGunner.weapons["Secondary Weapon"]["Fire Range"] = ""; var sniper = object(soldier); sniper.pointsCost += 30; sniper.validTargets.target1 = "Infantry"; sniper.weapons["Main Weapon"]["Weapon Type"] = "Savage .308"; sniper.weapons["Main Weapon"]["Fire Range"] = 20; sniper.weapons["Secondary Weapon"]["Weapon Type"] = "JCP .45"; sniper.weapons["Secondary Weapon"]["Fire Range"] = 3; var demolitions = object(soldier); demolitions.pointsCost += 30; demolitions.validTargets.target1 = "Infantry"; demolitions.validTargets.target2 = "Light Armor"; demolitions.validTargets.target3 = "Artilery"; demolitions.validTargets.target4 = "Structures"; demolitions.weapons["Main Weapon"]["Weapon Type"] = "SMAW MK153"; demolitions.weapons["Main Weapon"]["Fire Range"] = 16; demolitions.weapons["Secondary Weapon"]["Weapon Type"] = "M1014 Combat Shotgun"; demolitions.weapons["Secondary Weapon"]["Fire Range"] = 1; var infantry = { rifleman: rifleman, heavyGunner: heavyGunner, sniper: sniper, demolitions: demolitions }; console.log(infantry); }); I start by creating an object function that accepts an object passed in, and sets it to the prototype of a constructor (that would allow me to create a new object linked to, and inheriting from, the initial passed in object) I initialized a solider object literal, and pass that into the object function while creating 4 new objects (rifleman, heavyGunner, sniper, demolitions) These four should inherit from and customize upon the soldier object. The way I understood inheritance is that the new objects (example. rifleman) would inherit properties from the old object (i.e. soldier) and change or add properties, affecting only the new (rifleman) object but not changing the old(solider) object. this works ok somewhat in my example, until it comes to nested objects. In the above example I have objects as values for some Object's properties. (i.e. validTargets and weapons) When I change or add these, all of the new objects seem to inherit the last declarations, from demolitions, as if demolitions is actually changing that part of the soldier object so that the other's inherit those properties. From my viewpoint, I expected these values to not be changed and that the 4 infantry types had no link to each other, but only to the soldier object. I apparently misunderstood something, or coded something wrong. Some minor notes: -I will be updating most of the "string" values to be objects, so for instance, the validTargets value of "Infantry" would actually be the infantry object, stating that any of the 4 solider types would be a valid target. - I intend to create weapons as their own viable objects in the future, and pass those objects instead of "strings" - I intend to extend this (once this is working) to create an armor object that contains armor type units, similar in structure to the infantry object. - If I can get this all to work, I may make this into a "simple" dice style battle game. but that is way off, I just want to get this nesting of objects to work with inheritance for now. Thanks in advance for any help you can provide. Here is a link to the "live" example. (not much different there except if you have firebug you can see the console.log method showing the objects, and how they are inheriting in properly from my POV.) Link to Live example... Blue Similar TutorialsHello, I have an Object, containing an object, containing an object....etc. So, it's an Object of objects. Not an Array of objects. And now I want to sort this Object of objects. Is there a "native" way in JavaScript to sort an object? Or do I understand it correctly, that I first have to convert the Object to an Array, and than perform an array.sort ? This question is just for my understanding of JavaScript, so I don't go into the wrong direction. Tnx in advance for any explanation. I'm having a javascript problem with nested elements. Consider an example in which you have two nested elements with element 2 being inside of element 1 and only element 1 has an onmouseout event handler. <div style="position:relative;border:1px solid red;width:300px;height:300px" onmouseout="alert('whatever')"> //element 1 <div style="position:absolute;border:1px solid blue;left:50%;top:50%;margin-left:-50px;margin-top:-50px;width:100px;height:100px">//element 2 </div> </div> The 2 problems here are as follows: 1- Moving the mouse pointer over element 2 from element 1 causes a onmouseout with element 1. But this is a minor problem. 2- Moving the mouse pointer from element 2 back to element 1 causes a mouseout with ,I believe, element 2 even though there is no onmouseout event handler here. This is a major problem. Is problem #2 due to possibly an automatic inheritance of the onmouseover handler from element 1 onto element 2 OR is it the result of event capturing or what else? I can't tell either way. If it's due to inheritance how do you stop this from taking place? The strange thing is that tutorials give this kind of scenario with element 2 inside of element 1 with both elements having the same event handler but they don't say what happens in this case with just one element having a specific event handler. Thank you. I'm trying to reuse some code in a different context to do a different job. The code to be reused contains hundreds of lines similar to a = new b.c.d(e,f) with different value for e and f. I need to create a new user defined object with the structure b.c.d. I've made numerous attempts along the lines of: Code: function d (e, f) { this.e = e; this.f = f; } function c () { this.d = d (e, f); } function b () { this.c = c; } var a = new b.c.d("test", "message"); with various permuations of functional declarations. However I get error message "Object expected" or "b.c.d is null or not an object" at the final line of the example. It works with the test line var a = new d("test", "message") but not when I start to build up the expression. How should I define of b.c.d? Hi, I am having trouble with a recursive function I created to list out the indexes and values of various nested objects. Code: var macros={ CTRL: { ALT: { ENTER: "<br />", P: "<p>.</p>", A: "<a href=\"\">.</a>", _1: "<h1>.</h1>", _2: "<h2>.</h2>", _3: "<h3>.</h3>", _4: "<h4>.</h4>", _5: "<h5>.</h5>", _6: "<h6>.</h6>" } } }; I want to print out the whole 'bread crumb trail' to each object, ie CTRL ALT 6: <h6>.</h6>, but at the moment my function prints out CTRL ALT twice for 'ENTER' and then never again. The function: Code: function printObj(obj) { for(i in obj) { var n=i.replace("_", ""); document.write(n); if(typeof obj[i]=="string") { document.write(":"); document.write(" "+obj[i].replace(/</g, "<").replace(/>/g, ">")); } else { document.write(n); } if(typeof obj[i]=="object") printObj(obj[i]); document.write("\n"); } } printObj(macros); The current output: Code: CTRLCTRLALTALTENTER: <br /> P: <p>.</p> A: <a href="">.</a> 1: <h1>.</h1> 2: <h2>.</h2> 3: <h3>.</h3> 4: <h4>.</h4> 5: <h5>.</h5> 6: <h6>.</h6> Any advice would be appreciated. Cheers, Gus Hi, I am a begginer in javascript, please help on below I want to create an object with nested objects array like following: var country{ var states=new array(); } var state { city,pincode } this should be called like var city= country[0].state[0].city; any idea will be appreciated This is a little hard to explain so I'm posting an example. Code: //NESTED FUNCTION I'M USING TO DEMONSTRATE MY QUESTION function foo(a) { this.x = 5; //USED TO SET THE VALUE OF X if( a == 0 ) return function(z) { return x = z; } //USED TO RETRIEVE THE VALUE OF X else if( a == 1 ) return function() { return x; } } //MAKES setX THE SETTER FUNCTION var setX = foo(0); //MAKES getX THE GETTER FUNCTION var getX = foo(1); print( "setX(25), not an instance: " + setX( 25 ) ); print( "getX(), not an instance: " + getX() ); print( "" ); //CREATES AN OBJECT INSTANCE USING FOO AS CONSTRUCTOR var q = new foo(); print( "value of x in object instance: " + q.x ); print( "" ); print( "setX(25), not an instance: " + setX( 25 ) ); print( "getX(), not an instance: " + getX() ); This code will output: Code: setX(25), not an instance: 25 getX(), not an instance: 25 value of x in object instance: 5 setX(25), not an instance: 25 getX(), not an instance: 25 Observations: It seems like this.x actually has two meanings. 1)x becomes a member of the "Function" object foo(). 2)x becomes a part of the constructor for prototype class foo. But why then does x revert back to the original value of 5 when I use foo as a constructor? Does javascript automatically save the original value on creation for a reason? What is going on behind the scenes to make this happen? Is this behavior part of an ontological model that makes sense? Similarly, if I change "this.x" to "var x" I can access the value of x but I can't change it. Not that that I should be able to, the syntax "var x" doesn't make x a member of foo anyway. But I'm still having trouble classifying the relationship "var x" has to the function. Anyways this is more of a tangent. My main question is above but if anyone has something to say about this, I'd be interested to hear it. It seems like all these behaviors have rules to them, but there is no conceptual model to think through that guide these behaviors. Or maybe I'm just ignorant. Enlighten me. What are the benefits of prototypal inheritance over classical inheritance?
What are the benefits of prototypal inheritance over classical inheritance?
Hello All, can someone pls help me with the error shown in firebug for the code below: Firebug error: Object.method is not a function Object.method('superior', function (name) { Constructor functions work until it gets to /* Super method template */. Thats where the error comes from. Code is from javascript - good parts. var mammal = function(spec) { var that = {}; that.get_name = function() { return spec.name; } that.says = function() { return spec.saying || ''; } return that; } var myMammal = mammal({name: 'Herbie', saying: 'Im herb the mammal'}); console.log(myMammal.get_name()); console.log(myMammal.says()); var cat = function(spec) { spec.saying = spec.saying || 'Meow!' var that = mammal(spec); that.purr = function(n) { var i, s = ''; for(i=0; i < n; i +=1) { if(s) { s += '-'; } s += 'r' } return s; } that.get_name =function() { return that.says() +' '+ spec.name +' '+ that.says(); } return that; } var myCat = cat({name: 'Henrietta!', saying: 'Im a pussycat'}) console.log(myCat.get_name()); console.log(myCat.purr(3)); /* Super method template */ Object.method('superior', function (name) { var that = this, method = that[name]; return function ( ) { return method.apply(that, arguments); }; }); /* Super method e.g. */ var coolcat = function (spec) { var that = cat(spec), super_get_name = that.superior('get_name'); that.get_name = function (n) { return 'like ' + super_get_name( ) + ' baby'; }; return that; }; var myCoolCat = coolcat({name: 'Bix'}); console.log(myCoolCat); var name = myCoolCat.get_name(); console.log(name); I'm trying my best to figure this out with google, but I've found 4 different syntaxes and can't get any of them to work. I need to have several classes extend another for my chess game. I need classes, Rook, Knight, Bishop etc... all extend from class Piece. can anyone help me with the syntax var Piece = Class.create(); Piece.prototype = { initialize: function(src, square){ //init stuff here }, setSqua function(square){ //sets the square of the piece }, } Rook.prototype = new Piece(); function Rook(src, square) { Piece.apply(src, square); } Thanks to anyone who helps Hi, I would like to know which is the best approach when trying inheritance with js - module pattern. In the example below, I want that parent.hi() be fired from child: Code: var parent = function(){ return{ hi: function(){ console.info('hi'); } } }(); var child = function(){ return{ bye: function(){ console.info('bye'); }, hi: function(){//look he parent.hi(); } } }(); child.hi(); Is there a better way to do this ? Thanks in advance First class: Code: function ClassOne(){ this.events = []; this.executeEvents = []; this.addEvents = function(event){ this.events.push(event); } this.addExecuteEvents = function(e){ this.executeEvents.push(e) } this.getEvents = function(){ return this.events; } } Second class: Code: function ClassTwo(){ this.add = function(e){ this.addEvents(e) } } ClassTwo.prototype = new ClassOne Here the second class extends the first class, now I want to create two objects of class two, Code: var b = new ClassTwo(); b.add('hello'); var c = new ClassTwo(); c.add('hi'); console.log(c.getEvents()) I just added one event on b and c each, but when I logged the c.getEvents(), it returns both 'hi' and 'hello' events. why?? What am I doing wrong?? how to solve this problem?? Thanks in advance Hi! This is probably a classic inheritance thing... I have two objects, C1 and C2. Both contains a callback method named 'callback'. Now, if I let C2 inherit from C1, then C1's 'callback' gets overridden by C2's. The problem is I still want C1's methods to access their own 'callback' method. Is this possible, and is it "valid"? Am I headed down disaster lane here? Should I re-think and refactor? Example: Code: function C1 () {}; C1.prototype.callback = function () { console.log('c1 called'); }; C1.prototype.call = function () { //do stuff this.callback(); }; function C2 () {}; C2.prototype = new C1(); C2.prototype.callback = function () { console.log('c2 called'); }; var obj = new C2(); obj.call(); Output: c2 called Regards Don please bear with my noobishness, but i've been trying for many hours to understand what is going on behind this code: ** Code: function Person() { document.write('constructor: <br/>'+this.constructor); //displays Person constructor this.name = "Rob Roberson"; this.age = 31; } function Employee() { document.write('<br/>constructor: <br/>'+this.constructor); //displays Person constructor this.dept = "HR"; this.manager = "John Johnson"; } Employee.prototype = new Person(); var Ken = new Employee(); document.write('<br/>'+Ken.constructor); //displays Person constructor document.write('<br/>name:'+ Ken.name + '<br/>age:' + Ken.age + '<br/>dept:' + Ken.dept + '<br/>manager:' + Ken.manager ); //displays all properties correctly *** from what i've read, every object references a prototype. in this case, the Employee function will automatically reference a prototype with 'constructor' as its initial value. this command: Employee.prototype = new Person(); will replace the Employee function's prototype to an instance of Person. so now Employee function's prototype will contain both name and age properties, BUT, and this is where i get lost, ITS CONSTRUCTOR PROPERTY GETS REPLACED! so how does: var Ken = new Employee(); actually construct an instance of Employee if the reference to its constructor has been replaced by an instance of Person that only contains name and age properties? how is Ken ever initialized by Employee constructor? Okay so if you go to this website: http://gameusd.com/ You can pick your game & country -- say its world of warcraft US And then you pick your realm and faction, and then it gives you the prices on those particular realms/factions. What i wanted to know was if it was possible to somehow make a program that fetches the prices of EVERY single realm/faction and lists them all side by side and in order of lowest to highest price or whatever. Would massively appreciate if somehow could tell me if its possible. Because obviously doing it all manually would be a huge pain in the *** and take hours. Hi Friends, i have a smal task i.e i have textbox1 ,botton,textbox2 when i enter 21 value then i click button its get in sama row values in textbox2. i have xml file like this <DATAPACKET > <ROWDATA> <R_ID>101</R_ID> <R_NAME>R-12</R_NAME> <R_TEMP>4.266</R_TEMP> <R_COLOR>White</R_COLOR> </ROWDATA> <ROWDATA> <R_ID>20</R_ID> <R_NAME>R-22</R_NAME> <R_TEMP>4.266</R_TEMP> <R_COLOR>Green</R_COLOR> </ROWDATA> <ROWDATA> <R_ID>21</R_ID> <R_NAME>R-32</R_NAME> <R_TEMP>4.266</R_TEMP> <R_COLOR>White</R_COLOR> </ROWDATA> <ROWDATA> <R_ID>104</R_ID> <R_NAME>R-134A</R_NAME> <R_TEMP>4.246</R_TEMP> <R_COLOR>Light Blue</R_COLOR> </ROWDATA> <ROWDATA> <R_ID>21</R_ID> <R_NAME>R-290</R_NAME> <R_TEMP>4.246</R_TEMP> <R_COLOR>White</R_COLOR> </ROWDATA> <ROWDATA> <R_ID>31</R_ID> <R_NAME>R-401A</R_NAME> <R_TEMP>4.246</R_TEMP> <R_COLOR>Pink</R_COLOR> </ROWDATA> <ROWDATA> <R_ID>32</R_ID> <R_NAME>R-401B</R_NAME> <R_TEMP>4.264</R_TEMP> <R_COLOR>White</R_COLOR> </ROWDATA> <ROWDATA> <R_ID>108</R_ID> <R_NAME>R-402A</R_NAME> <R_TEMP>4.426</R_TEMP> <R_COLOR>Light Greem</R_COLOR> </ROWDATA> <ROWDATA> <R_ID>129</R_ID> <R_NAME>R-402B</R_NAME> <R_TEMP>4.266</R_TEMP> <R_COLOR>White</R_COLOR> </ROWDATA> <ROWDATA> <R_ID>110</R_ID> <R_NAME>R-404A</R_NAME> <R_TEMP>4.246</R_TEMP> <R_COLOR>Orange</R_COLOR> </ROWDATA> <ROWDATA> <R_ID>121</R_ID> <R_NAME>R-407A</R_NAME> <R_TEMP>4.267</R_TEMP> <R_COLOR>White</R_COLOR> </ROWDATA> <ROWDATA> <R_ID>122</R_ID> <R_NAME>R-408A</R_NAME> <R_TEMP>4.267</R_TEMP> <R_COLOR>White</R_COLOR> </ROWDATA> <ROWDATA> <R_ID>113</R_ID> <R_NAME>R-409A</R_NAME> <R_TEMP>4.267</R_TEMP> <R_COLOR>White</R_COLOR> </ROWDATA> <ROWDATA> <R_ID>134</R_ID> <R_NAME>R-407C</R_NAME> <R_TEMP>4.264</R_TEMP> <R_COLOR>White</R_COLOR> </ROWDATA> <ROWDATA> <R_ID>115</R_ID> <R_NAME>R-410A</R_NAME> <R_TEMP>4.426</R_TEMP> <R_COLOR>White</R_COLOR> </ROWDATA> </DATAPACKET > then i try this hear i get all values function gettxt() { results = new Array; var searchterm = document.getElementById("searchme").value; if (searchterm == null || searchterm == "") { alert("Enter textbox value"); return false; } var istrlen1 = searchterm.length; var tempname1; if (istrlen1 == 1) { tempname1 = searchterm; } if (istrlen1 == 2) { tempname1 = searchterm; } if (istrlen1 == 3) { tempname1 = searchterm; } if (istrlen1 == 4) { tempname1 = searchterm; } for (i = 0; i < x.length; i++) { var name = x[i].getElementsByTagName("R_ID")[0].firstChild.nodeValue; var name1 = x[i].getElementsByTagName("R_NAME")[0].firstChild.nodeValue; var exp = new RegExp(tempname1, "i"); if (name.match(exp) != null) { y = y + 1; results.push(name1); } } textbox2.value = results; } i try the above code hear small problom when i enter 21 and click button its display 21,121,123... related values i dont want like that for example textbox1=21 buttonclick textbox2=R-32,r-407A,r-408A like that i dont want like that i want textbox1=21 buttonclick textbox2=R-32 only in same row value please any one knows well in js please resolve my problom Hi guys, Im not sure my subject decsription gives an exact description of what i am after but i will try and explain my requirements a bit better. I have an header menu there are items in this menu but there are a lot of them and if you try view on a normal 1024 x 760 you have to horizontal scroll to view all the items, but on my monitor 1920 x 1080 it is fine. I don't want to do it this way since I hate having to scoll both horizontal and vertical. I would like to be able to change the items on this header to become a rollover dropdown menu when they would normally be hidden becuase of the screen width. I have seen this done before I am just unsure about how to implement this. can anyone point me in the direction of some good resources for this? Thanks EDIT---------------------------------------------------------------------------------------------- I am using jQuery if that make it easier to fine a script that would do this im new to webpage programming,but do hav some basic c/c++ programming skill. in order for me to understand the following codes, what should i read? i had read thru w3schools.com html and javascript tutorials but it is stil difficult for me to understand the codes,can somebody help me?thanks! Code: function getQuery() { var scoping = "&project=${currentProject}&projectScopeUp=" + projectScopeUp + "&projectScopeDown=" + projectScopeDown; var paging = "&pagesize=100"; return { "currentProject" : "/iteration:current/project", "#storyType" : "/typedefinition?query=(Name = \"Hierarchical Requirement\")", "taskUnit" : "${iteration/workspace/workspaceConfiguration/taskUnitName}", "storyStates" : "${#storyType/attributes[name=schedule state]/allowedvalues/stringvalue}", "iteration" : "/iteration:current?fetch=name,objectid&order=StartDate", "iterations" : "/iterations?fetch=name,objectid&order=StartDate,Name&project=${currentProject}&projectScopeUp=false&projectScopeDown=false" + paging, "users" : "/users?fetch=displayname,loginname,emailaddress,objectid" + paging, "tasks" : "/tasks?fetch=taskindex,name,objectid,formattedid,owner,blocked,estimate,todo,actuals,state,workproduct&query=(Iteration = ${iteration})" + scoping + paging, "stories" : "/hierarchicalrequirement?fetch=rank,blocked,formattedid,name,objectid,owner,project,schedulestate,taskestimatetotal,taskremainingtotal,taskactualtotal,tasks&order=Rank&query=(Iteration = ${iteration})" + scoping + paging, "defects" : "/defect?fetch=rank,blocked,formattedid,name,objectid,owner,project,schedulestate,taskestimatetotal,taskremainingtotal,taskactualtotal&order=Rank&query=(Iteration = ${iteration})" + scoping + paging, "defectsuite" : "/defectsuite?fetch=rank,blocked,formattedid,name,objectid,owner,project,schedulestate,taskestimatetotal,taskremainingtotal,taskactualtotal&order=Rank&query=(Iteration = ${iteration})" + scoping + paging, "testsets" : "/testset?fetch=rank,blocked,formattedid,name,objectid,owner,project,schedulestate,taskestimatetotal,taskremainingtotal,taskactualtotal&query=(Iteration = ${iteration})" + scoping + paging }; } |