JavaScript - Passing Object By Reference Question
My question is commented in the script:
Code: function Love(){ var req = { ring : 'gold', money : 'a lot', commitment : 'long-term' } this.loveReqs = function(){ return req; } } var you = new Love(); var details = you.loveReqs(); details.ring = "silver"; console.log(details.ring); var me = new Love(); var details = me.loveReqs(); console.log(details.ring); // why does this return gold and not silver if req is passed by reference and we already changed its value above and so it's pointing to the same memory position? Similar TutorialsHi, I've had problems in the past understanding this, however, after reading this tutorial, I understand. In some languages, like VB6, I notice the "byVal" and the "byRef" is specifically used. In javascript, I don't notice those specifics typed in functions. Is the "default" by value when using in a function to change a parameter? If it is, what is the syntax for using by reference, or is that ever used? My question arises from this notation taken from here: Quote: Note that it is the value that a has at the time that it is passed into the function that gets substituted into the argument and not the value that the original variable has at that point in the processing. It is the values in the parameters that the function uses and not the variables. This is called pass by value . In those languages where you can pass the actual variable into the function instead of just passing its value the method used to do so is called pass by reference . Had we been able to pass the variables into the function by reference rather than by value then the final value in b would have been -16 instead of -14. Here is the example (passing by value): Code: function myfunction(y, z) { a += y; b -= z; } var a = 0; var b = 10; var c = 3; var d = 4; var e = 2; myfunction(c, d); myfunction(d, e); myfunction(9, 2); myfunction(b, a); Results: myFunction(c, d); output: 0 + 3 = 3(y), 10 - 4 = 6(z) myFunction(d, e); output: 3 + 4 = 7(y), 6 - 2 = 4(z) myFunction(9, 2); output: 7 + 9 = 16(y), 4 - 2 = 2(z) myFunction(b, a); output: 2 + 16 = 18(y), 2 -16 = -14(z) Thanks! The goal is for selectedDay to be assigned the value of the system variable Mainpackage.subclass0.subclass1.firstDay and then incremented by two days. Mainpackage.subclass0.subclass1.firstDay needs to be unchanged. Important system variable in red. To be 'manipulated and used' variable in green. Even with an intermediary, third, dummy variable it doesn't work: Code: //Declarations and instantiations var systemDate = new Date(); var selectedDay = new Date(); Mainpackage.subclass0.subclass1.firstDay ; //Assignments and manipulations systemDate = Mainpackage.subclass0.subclass1.firstDay ; selectedDay = systemDate ; selectedDay .setDate( selectedDay .getDate()+2); //Logging console.log('Mainpackage.subclass0.subclass1.firstDay: ' +Mainpackage.subclass0.subclass1.firstDay +'\n' +'systemDate: ' +systemDate +'\n' +'selectedDay :' +selectedDay +'\n'); Console log is: Code: Mainpackage.subclass0.subclass1.firstDay: Tue Aug 24 2010 00:00:00 GMT-0400 (Eastern Daylight Time) systemDate: Tue Aug 24 2010 00:00:00 GMT-0400 (Eastern Daylight Time) selectedDay: Tue Aug 24 2010 00:00:00 GMT-0400 (Eastern Daylight Time) It doesn't work in my webapp : All variables change at the same time. Hi, I have this ajax routine... Code: function xhr_get(target_str,async){ var sync=true; if(async){sync=false;} var xhr = new XMLHttpRequest(); xhr.open('GET', target_str, sync); if(sync==false){ xhr.onreadystatechange = function () { if (xhr.status === 200) { try{ var ii =JSON.parse(xhr.responseText);} catch (exception) { } if(ii){ return ii; }else{ alert(xhr.responseText); return false; } } else { alert(xhr.status+' '+target_str);return false; } }; xhr.send(null); }else{ xhr.send(null); try{ var ii =JSON.parse(xhr.responseText);} catch (exception) { } if(ii){ return ii; }else{ alert(xhr.responseText); return false; } } } now if I alert(ii) on success the data I am looking for (specifically ii.content) shows up in the alert as expected however when calling from another javascript function, ii is false ???? please explain, Code: function call_change_val(fld,vm_id){ var str='?_f=load_edit_fld&_ctl_fld='+fld+'&vm_id='+vm_id+'&fld='+fld+'&width=80'; i = xhr_get('ajax/val_main_loader.php'+str,true); ////////////////////// alert(i); or alert(i.content) here both give be a blank popup///////////////// showdiv('c_change_'+fld); setih('c_change_'+fld,i.content); } I expected alert(i) to say Object or similar, getting nothing I am confused about what the return keyword is actually returning when returning an object, a primitive, or a function. My confusion is compounded by the fact that I'm not sure if a function is an object or not. According to the book JavaScript Programmer Reference it is: "All functions in JavaScript are first class objects , meaning they can be passed around like any other object reference. In fact, regardless of how they are created, functions are instances of a global object named (aptly) Function." However, someone else states that a function is not an object. An object is a set of primitives and references. A function is executable code. Functions become objects through the use of the new operator. Yet, in the book I mentioned, it says you don't need the new keyword to execute the function as an object, as it already inherits from the object Function when the function keyword is used: Code: function functionName([argname1 [, ...[, argnameN]]]) { statements; } So there's one source of contradiction. Now the bigger issue is what is going on when the return keyword is used. Notice the Validation() function returns an object as its last expression. This technique is common, where you return an object which contains functions in form of object notation. I believe this is done so that we create a closure so that when the intepreter exits the Validation() method, since we created a closure by returning an object, which contains the inner functions addRule and getRule, the local variables of Validation() are not destroyed, given that we can reference them through the two inner functions that make use of the local variables of the outer function. So when we use the return keyword on an object literal, and then exit the function, when we call one of the inner functions as we do later: Code: var rule = $.Validation.getRule(types[type]); essentially getRule() is called, passes an argument, which is received by the inner function as parameter we call name: Code: getRule : function(name) { return rules[name]; } First, note that the return {} is written in object notation, therefore making getRule a local variable and, thus, private function only accessible through the namespace of Validation(). Validation() declares the rules local variable and because of the closure, we can access the rules local variable through the getRule() inner function. *****Here's the part that really thows me off. We return rules[name]. So let's say name is equal to email. This is an associative array so email (held in name) is a property of rules. So here we return the object's property: Code: return rules[name]; And then assign it to a local variable called rule: Code: var rule = $.Validation.getRule(types[type]); So when we return an object rules[name], do we return a reference to an object or a value? In other words, by returning rules[name], where name is equal to email, are we then returning a reference to the following object literal: Code: email : { check: function(value) { if(value) return testPattern(value,".+@.+\..+"); return true; }, msg : "Enter a valid e-mail address." } And if we are returning a reference, by returning a reference, are we essentially pointing to this object when we assign it to rule? In other words, the variable rule is just pointing to the object literal? And is that the reason we can then access the check function or msg local variable through rule using dot notation, because rule points to the email object literal? Now the ultimate brain twist for me is that if a function is an object, then why when return a function, it returns a value, such as a boolean, if an object only returns a reference and not the value? Code: //Validation is a local variable as it is in a self-executing anonymous function. The purpose of the said anonymous function is to pass the jQuery object as a parameter $ so the $() function will be in scope of the anonymous function and not interfere with other libraries that make use of the same function technique - in the global scope. (function($) { var rules = { email : { check: function(value) { if(value) return testPattern(value,".+@.+\..+"); return true; }, msg : "Enter a valid e-mail address." }, url : { check : function(value) { if(value) return testPattern(value,"https?://(.+\.)+.{2,4}(/.*)?"); return true; }, msg : "Enter a valid URL." }, required : { check: function(value) { if(value) return true; else return false; }, msg : "This field is required." } } var testPattern = function(value, pattern) { var regExp = new RegExp("^"+pattern+"$",""); return regExp.test(value); //The test() method is built into javascript } return { addRule : function(name, rule) { rules[name] = rule; }, getRule : function(name) { return rules[name]; } } } /* Form factory */ var Form = function(form) { var fields = []; $(form[0].elements).each(function() { var field = $(this); if(field.attr('validation') !== undefined) { fields.push(new Field(field)); } }); this.fields = fields; } Form.prototype = { validate : function() { for(field in this.fields) { this.fields[field].validate(); } }, isValid : function() { for(field in this.fields) { if(!this.fields[field].valid) { this.fields[field].field.focus(); return false; } } return true; } } /* Field factory */ var Field = function(field) { this.field = field; this.valid = false; this.attach("change"); } Field.prototype = { attach : function(event) { var obj = this; if(event == "change") { obj.field.bind("change",function() { return obj.validate(); }); } if(event == "keyup") { obj.field.bind("keyup",function(e) { return obj.validate(); }); } }, validate : function() { var obj = this, field = obj.field, errorClass = "errorlist", errorlist = $(document.createElement("ul")).addClass(errorClass), types = field.attr("validation").split(" "), container = field.parent(), errors = []; field.next(".errorlist").remove(); for (var type in types) { var rule = $.Validation.getRule(types[type]); if(!rule.check(field.val())) { container.addClass("error"); errors.push(rule.msg); } } if(errors.length) { obj.field.unbind("keyup") obj.attach("keyup"); field.after(errorlist.empty()); for(error in errors) { errorlist.append("<li>"+ errors[error] +"</li>"); } obj.valid = false; } else { errorlist.remove(); container.removeClass("error"); obj.valid = true; } } } /* Validation extends jQuery prototype */ $.extend($.fn, { validation : function() { var validator = new Form($(this)); $.data($(this)[0], 'validator', validator); $(this).bind("submit", function(e) { validator.validate(); if(!validator.isValid()) { e.preventDefault(); } }); }, validate : function() { var validator = $.data($(this)[0], 'validator'); validator.validate(); return validator.isValid(); } }); $.Validation = new Validation(); })(jQuery); Thanks for any response. I have the following code: [CODE] rtn += "<div class='crowelem' style='width:100px;'>"+panel.genSendButton(current.readNode())+"</div>"; [CODE] This is in a loop that generates rows in a DIV. current.readNode() is returning an object from a linked list, the method genSendButton looks like this: [CODE] MatchRequest.prototype.genSendButton = function (obj) { var rtnstr = null; if(obj.msNotified == 0) { rtnstr = "<input type='button' value = 'Notify' onClick=\"javascriptanel.sendNotification("+obj+")\"/>"; } else { rtnstr = "<input type='button' value='Already Notified' disabled='true' onClick=\"javascriptanel.sendNotification('"+obj.msID+"')\"/>"; } return(rtnstr) ; } [CODE] If you step into this code in a debugger, obj is correctly passed into genSendButton as an object of the appropriate class. The code in the if(obj.msNotified == 0) clause generates an error. The var obj resolves to NPanlel: (this happens to be the class of the object). Regardless of how I try to pass obj into the method sendNotification it doesn't resolve to an object. Can anyone shed any light on where my omission of intelligence is occurring? Any help would be greatly appreciated. Mrbub PHP Code: function $(x) { return document.getElementById(x); } function test(x) { alert(x.id); } function init() { var o = {}; o.id = "a"; $("one").addEventListener("click", function () {test(o);}); o.id = "b"; $("two").addEventListener("click", function () {test(o);}); o.id = "c"; $("three").addEventListener("click", function () {test(o);}); } window.onload = init; I have some code similar to this. When the HTML elements with id's "one", "two", or "three" are clicked, they all alert "c", but I want them to alert the respective values (a, b, and c). How can I pass the object by value and not by reference? I guess in this simple example you would just define two more objects, but my code is actually within a for-loop. The object properties are changed each iteration (ideally each iteration creates a new object) and then passed to the function. Hey all, This is a problem that I've tried various ways round - consider the following code: Code: if (window.XMLHttpRequest) { this.xhr = new XMLHttpRequest(); } else if (window.ActiveXObject) { this.xhr = new ActiveXObject("Microsoft.XMLHTTP"); } this.xhr.onreadystatechange = function () { if(this.readyState == 4) { if(this.status == 200) { editor.loadObject.doLoad(); } else window.console.log("Loader: Loader Error code " + xhr.status); } } the code is called from my "loader" object which in turn is loaded from another object in this case "editor" (editor initiates the loader object by this.loadObject = new loader(this.ident + "loader");). In the example above I have had to hard-code the variable "editor" (i.e. the original object) because when I define this.xhr.onreadystatechange as a function, anything outside the function is outside of it's scope, so I can't for example define this.callerObject and put it in place of editor. This is a nuisance as you can imagine - Any ideas how to do this? Many thanks Edd Hi Everyone, I have the following problem that I have been trying to figure out for a few hours now and am hoping someone can give me a help out. I am opening a popup - this popup is solely to take an image url and as such has one field. On this 1st popup I have a 'button' which when clicked launches a 2nd popup window containing a file browser. The user selects the file by double clicking on the image they want, the url is passed back to the 1st popup, poulating the field and the 2nd popup is closed. Work perfectly in FF etc.. but in IE7 and IE8 it will not work. I am using the following function, linked to the button in the 1st popup, to open the 2nd popup window pass across the name of the field and the window object to the 2nd window. Code: function popupTwoInit(file_path, field_name, win) { var w = window.open(file_path, null, 'toolbar=yes,menubar=yes,width=900,height=600'); w.fileFileField = field_name; w.fileFileWin = win; } Where w is holding the window object created by the window.open, field_name is the name of the field on the popup that I wish to pass back a value to and win is the window object of the 1st popup. I am using this function as the callback to poulate the field in the 1st dialog after an image in the 2nd dialog has been selected: Code: filebrowser_callback(url) { window.fileFileWin.document.forms[0].elements[window.fileFileField].value = url; window.fileFileWin.focus(); window.close(); } So this function accesses the passed through window object and field name from the window.open function, populates the field, gives the 1st popup focus and closes the 2nd popup. I thought about using opener in the 2nd popup to access the window object and field in the 1st popup but opener seems to refer to the main page in the browser - perhaps because I am using 2 popups OR I have got that wrong. Like I say works perfectly in FF but IE is always undefined for both 'window.fileFileWin' & 'window.fileFileField' which seems to suggest that the object is not interpreted by IE in the first function? I am a PHP developer with limited Javascript knowledge so any help would be great. Thanks very much. if location is a property of window object that returns a string and im appending .indexOf() to location why is it not working?
I was going through an article on JavaScript objects on "http://www.howtocreate.co.uk/tutorials/javascript/javascriptobject" and there I read Quote: Intrinsic objects - variable types with constructors. * Array * Boolean * Date * Function * Image * Number * Object * Option * Regular Expression * String does it mean that, whenever I want to use any of these objects, I have to create it using new and only then I can use its properties or methods ? 1) There are other objects like document, history, location, navigator, parent and screen. If objects which need to be created using constructor are called intrinsic objects , then what are other objects which can be used without constructor are called as ? Array, Boolean, Image, Date etc all start with capital letter. While document, history, navigator etc start with lower case letter. Why is that ? Is there any difference between objects that start with upper case and those start with lower case ? Are they known by different names ? Thanks The following code snippet: (this.inputArray is already defined and initialized prior to this code sequence) if(this.inputArray.length >= 0) { this.inputArray[this.inputArray.length] = new Object(); this.inputArray[this.inputArray.length].type = 'pcDisp'; this.inputArray[this.inputArray.length].data = a; } the first line in the code block should create a new array item and initialize it with the various assigments in the next lines. But Firefox complains "this.inputArray[this.inputArray.length] is not defined". This is very disconcerting because the code has to create array items with different data based on conditionals. So I must be able to automatically create new items as necessary. I thought that javascript had 'late binding', but maybe that doesn't apply here. So, does anyone have a clue for me? This is a constructor function. PROC will be an instantiation of another constructor. It will have a copy of GLBS. function _CALC_ELEMENTS(ELEM, GLBS, PROC) // PROC will also have a copy of GLBS. So, techincally, how could I access the copy of GLBS in PROC, via instance of _CALC_ELEMENTS. If I can do this, I do not need to include it directly. (GLBS is yet another object instantiated via constructor) I am just concerned that there are two copies when only one is necessary. Thanks for thoughts on this JK Hello, I'm trying to write my class with member properties and functions like below. What I want to learn is that is there any problem to use prototype object in the class that we want to use with it? I asked because I generally see that prototype object definition and member functions and properties created outside of the class unlike my class that I wrote like below. Is there any problem writing my class like below? Thanks. Code: function Point() { Point.prototype.x = this._x; Point.prototype.y = this._y; function _setX(x) { this.x = x; } Point.prototype.setX = _setX; function _setY(y) { this.y = y; } Point.prototype.setY = _setY; function _show() { alert(this.x + this.y); } Point.prototype.Show = _show; } function callMyClass() { var p = new Point(); p.setX(3); p.setY(5); p.Show(); } function get_price() { var the_price=1000; if (this.speed=="500MGz") the_price+=200; else the_price+=100; if (this.hdspace=="15GB") the_price+=50; else the_price+=25; if (this.ram=="128MB") the_price+=150; else the_price+=75; return the_price; } function computer(speed,hdspace,ram) { this.speed=speed; this.hdspace=hdspace; this.ram=ram; this.price=get_price; } var work_computer=new computer("2GHz","80GB","1GB"); var home_computer=new computer("1.5GHz","40GB","512MB"); var laptop_computer=new computer("1GHz","20GB","256MB"); var work_computer_price=work_computer.price(); var home_computer_price=home_computer.price(); var laptop_computer=laptop_computer.price(); ___________________________________________________ In the above code, the line I'm having trouble with is marked red. Why is it that when I call the method using ... this.price = get_price; It works fine. But if I assign the object this.price with like this... this.price = get_price(); I get an error? Isn't get_price() a function? So shouldn't the parenthesis be included when the method is called? Why are we suppose to leave out the parenthesis?! I'm confused. Thanks! Hi All, i'm attempting to code using Java script a simple trading bot to use for automatic trading. Im new to javascript but not to programming. I have to pass data to the server to login and to trade and have managed to read the xml data returned in order to check prices from the non secure side of the site. The data to be passed is in the form; "https://live.bullionvault.com/secure/j_security_check?j_username=XXX&j_password=YYY" I can open another window by having this in my code but wish to stay within the program window i'm using for the bulk of the program. Hope to gain some pointers in order that i can progress further Many thanks Glenn Hello, i'm working on a 3 page survey. When hitting next, previous, or submit it passes the values of all the questions to the next page. I've got the whole thing working correcting except for one thing: When the box is "not" checked it passes no value. I'm needing it to have a value of "1" when checked and a value of "0" when not checked, and currently when its not checked and i pass the info it leaves it blank. I'd post the whole code to one of the pages but it's long , so i'll post the snipits of the code. Code: <script type="text/javascript"> /* <![CDATA[ */ function processQueryString() { var formData = location.search; formData = formData.substring(1, formData.length); while (formData.indexOf("+") != -1) { formData = formData.replace("+", " "); } formData = unescape(formData); var formArray = formData.split("&"); for (var i=0; i < formArray.length; ++i) { //document.writeln(formArray[i] + "<br />"); var sDataName = formArray[i].split("=") switch (sDataName[0]) { case ".lib_use": for (var j=0; j < document.getElementsByName(".lib_use").length; ++j) { if (document.getElementsByName(".lib_use").item(j).value == sDataName[1]) { document.getElementsByName(".lib_use").item(j).checked = true; //alert("lib_use set"); } } break; case ".lib_comp": if (sDataName[1] == 1) { document.getElementsByName(".lib_comp").checked = true; document.getElementsByName(".lib_comp").value= 1; } else { document.getElementsByName(".lib_comp").checked = false; document.getElementsByName(".lib_comp").value= 0; } break; default: alert("not caught = " + sDataName[0]); continue; } } } /* ]]> */ </script> <input type="checkbox" name=".lib_comp" id="lib_comp" value="1" /> The first case that i showed in my code is a radio button, and it passes correctly, i just wanted to show the "format" i was using in a working sense. The 2nd case is an example of the check boxes. Thanks for looking at this, and giving any suggestions you might have! Hi, every time I try and alert: [ { number:0, secondnumber:0 }, { number:2, secondnumber:1 }, { number:1, secondnumber:2 } ] it just shows [object object], [object object], [object object]. Why is this and what can I do to make the record be shown as it is above in an alert? Thanks. I created a method for displaying an object's properties: Code: renderfunction = false; function showProperty (object, property) { document.write ('<td class="type">' + (typeof object[property]) + '</td>' + '<td class="name">' + property + '</td>'); document.writeln('<td class="value">' + ( (typeof object[property] != 'function') ? object[property] :( (property != 'showProperties') ? ( renderfunction ? object[property]() : ('<span class="self">NOT RENDERED</span>') ) : ('<span class="self">THIS</span>') ) ) + '</td>'); document.writeln('<td class="hasOwnProperty" >' + ( object.hasOwnProperty(property) ? "Local" : "Inherited" ) + '</td>'); if (typeof object[property] == 'function') { document.writeln ('<td class="function">' + object[property] + '</td>'); } else { document.writeln ('<td class="function"> </td>'); } } As long as renderfunction = false, the object is fine coming out of this function. However, if I change renderfunction to true, all my properties become undefined. Why isn't this working as I expect it to? How should I fix it? Thanks in advance, -Brian. I can't get any info from Firebug except that one line, uncaught exception [object Object]. The code fully worked, then I needed to make it dynamically create Sortables from the scriptaculous library based on how many X were in a table in my database, which I've done, and I'm thinking it may be a simple slight parse error of some type, I'm not too good with Javascript, because now my script barely works. I've double checked the script's source code, the PHP variables are exactly what they should be. Code: print<<<HERE Sortable.create('sortlist$box', { tag: 'img', overlap:'horizontal',constraint:false, containment: $list, dropOnEmpty: true, onChange: function(item) { var list = Sortable.options(item).element; if(changeEffect) changeEffect.cancel(); changeEffect = new Effect.Highlight('changeNotification', {restoreColor:"transparent" }); }, onDrop: function(item) { var thing=Sortable.options(item).element.identify(); var anchors = document.getElementById(thing).childNodes.length-2; if(anchors > 20){ alert('This box had 20 creatures in it already, your last action has not been saved.'); window.location.reload(); } else{ new Ajax.Request("saveImageOrder.php", { method: "post", parameters: { data: Sortable.serialize("sortlist$box") } }); } } }); HERE; $box++; } ?> }); </script> if you solve this I'll send ya $10 via paypal Dear all, I'm passing the variables myTitle and myLink to form.php using javascript. This is the way I'm doing it: Code: <a href='form.php?title=" + myTitle +"&link="+myLink+">Click me</a> It's working great but sometimes myTitle and myLink contain the plus character (+). When this happens it's not passed. In the case of the title, it's just a problem of looks but in the case of the link, well, the link won't work without the character. As an example if the title is: Laptop + Accessories What is passed is: Laptop Accessories What can I do to pass also the plus character?? Thanks a lot!! |