1. This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn More.
  2. Guest, PO has ceased our separate tiering and adopted Smogon tiers for SM. More information and updates here.

    Dismiss Notice

[Client Scripting] How do I get an object value in a variable without the variable being linked to the object? [Solved]

Discussion in 'Server and Client Scripting' started by Nightfall Alicorn, Feb 8, 2015.

  1. Nightfall Alicorn

    Nightfall Alicorn Left Pokémon Online, most likely not coming back.

    Joined:
    Oct 15, 2013
    Messages:
    491
    Likes Received:
    171
    PO Trainer Name:
    Nightmare Moon
    I've been browsing around but I don't know what to do. Best way to explain is showing an example:

    Code (JavaScript):
    1. // Global Variables
    2. var objData = {};
    3. objData.entry = ["default value"];
    4.  
    5. // PoScript Here
    6. var vTest = objData.entry;
    7.  
    8. vTest.push("abc");
    9.  
    10. print(objData.entry);
    The result I want from that print is just "default value" being in that object array. But vTest is being treated as a link to objData.entry and changed the contents to ["default value", "abc"] making it print "default value" and "abc" together.

    Basically I want objData.entry and vTest to be treated as separate values. So if I change one, the other remains untouched.
     
  2. RedJoker25

    RedJoker25 Resident Lurker Server Moderator Article Contributor Server Moderator Article Contributor

    Joined:
    Apr 5, 2011
    Messages:
    269
    Likes Received:
    54
    PO Trainer Name:
    RedJoker25
    One thing you could try instead of assigning objData.entry directly to vTest is to use a loop to push the values of objData.entry into vTest. Something like

    Code (javascript):
    1. var vTest = [];
    2. for (i = 0; i < objData.entry.length; i++){
    3.     vTest.push(objData.entry[i]);
    4. }
    Not sure how viable this is for what you're doing though.
     
  3. Crystal Moogle

    Crystal Moogle Ayaya~

    Joined:
    Jul 19, 2010
    Messages:
    3,204
    Likes Received:
    530
    PO Trainer Name:
    Hanako
    Code (JAVASCRIPT):
    1. var vTest = objData.entry.concat()
    2. //or
    3. var vTest = objData.entry.slice()
    Javascript doesn't provide a built-in way to create a deep copy of an object, so we have to use other functions to get around it. Note that this will only work with arrays, since slice/concat are array functions. Objects will act the same, to get around that we can use JSON.parse. This will also work on arrays if you want to use it to create a function for both arrays and objects.

    Code (JAVASCRIPT):
    1.  
    2. var vTest = JSON.parse(JSON.stringify(objData))
     
  4. Nightfall Alicorn

    Nightfall Alicorn Left Pokémon Online, most likely not coming back.

    Joined:
    Oct 15, 2013
    Messages:
    491
    Likes Received:
    171
    PO Trainer Name:
    Nightmare Moon
    The concat function for array works perfectly. Thanks again, Crystal.

    So if I'm going to need a deep copy of an object value. I have to have my object values all arrays and return the array[0] of that value?

    Is it possible to make a function that stores the array, string, boolean or an integer value of an object entry into a temp array[0] and then concat the first index into a variable and return its value as a deep copy of the correct value type?

    Like:
    Code (JavaScript):
    1. var vDeepValueCopy = funDeepObjCopy(objValueToReturn);
    Sorry if it sounds confusing.
     
  5. Crystal Moogle

    Crystal Moogle Ayaya~

    Joined:
    Jul 19, 2010
    Messages:
    3,204
    Likes Received:
    530
    PO Trainer Name:
    Hanako
    The JSON.parse(JSON.stringify(variable)) method works for any type that isn't functions or dates (although I do believe ints/strings don't need it, but it's nice to have consistency).
     
  6. Nightfall Alicorn

    Nightfall Alicorn Left Pokémon Online, most likely not coming back.

    Joined:
    Oct 15, 2013
    Messages:
    491
    Likes Received:
    171
    PO Trainer Name:
    Nightmare Moon
    I've just been playing around with the code and made this. I don't know if this would work for all value types but I hadn't been able to typeOf test the results yet. But I'm hoping this will work for all types.
    Code (JavaScript):
    1. function funObjEntryDeepCopy (text) {
    2.     if (text == undefined) {
    3.         return "Error: Object undefined or doesn't exist.";
    4.         }
    5.     var vInputArray = [text];
    6.     var vBlankArray = [];
    7.     var vDeepCopy = vBlankArray.concat(vInputArray);
    8.     return vDeepCopy;
    9.     }
    If I return "return vDeepCopy[0];" it be still linked.

    I try that JSON.parse and JSON.stringify method.
     
  7. Nightfall Alicorn

    Nightfall Alicorn Left Pokémon Online, most likely not coming back.

    Joined:
    Oct 15, 2013
    Messages:
    491
    Likes Received:
    171
    PO Trainer Name:
    Nightmare Moon
    I've spent most of the day yesterday trying to make a function to de-link and store object values in a variable. So far I've managed to make something that works with arrays, booleans, integers and strings. I thought I share my work.

    I don't know how error proof it is but if someone as an idea for improvements that be great.
    Code (JavaScript):
    1. // DEEP COPY OBJECT ENTRY
    2. // ******** ******** ********
    3. function funObjectEntryCopy (object_value, type) {
    4.     // VALIDATE OBJECT VALUE
    5.     if (object_value == undefined) {
    6.         return String("");
    7.         }
    8.     // VALIDATE TYPE AND DEFAULT AS STRING IF NO TYPE
    9.     if (type == undefined) {
    10.         var vType = "string";
    11.         }
    12.     else {
    13.         var vType = type.toLowerCase();
    14.         }
    15.     // CHECK FOR AND RETURN ARRAY, UNLINK BY PUSH
    16.     if (vType == "array") {
    17.         var vArray = [];
    18.         for (x=0; x < object_value.length; x++) {
    19.             vArray.push(object_value[x]);
    20.             }
    21.         return vArray;
    22.         }
    23.     // GET NON-ARRAY OBJECT VALUE AND UNLINK BY CONCAT
    24.     var vInputArray = [object_value];
    25.     var vBlankArray = [];
    26.     var vDeepCopy = vBlankArray.concat(vInputArray);
    27.     // CHECK FOR AND RETURN INTEGER
    28.     if ( (vType == "int") || (vType == "integer") || (vType == "number") ) {
    29.         return parseInt(vDeepCopy);
    30.         }
    31.     // CHECK FOR AND RETURN BOOLEAN
    32.     if ( (vType == "bool") || (vType == "boolean") ) {
    33.         if (vDeepCopy == "true") {
    34.             return true;
    35.             }
    36.         if (vDeepCopy == "false") {
    37.             return false;
    38.             }
    39.         return String("[funObjectEntryCopy Error: Not a boolean.]");
    40.         }
    41.     // CHECK FOR AND RETURN STRING
    42.     if (vType == "string") {
    43.         return String(vDeepCopy);
    44.         }
    45.     return String(vDeepCopy);
    46.     }

    Example use:
    Code (JavaScript):
    1. var vArray = funObjectEntryCopy(objData.vArray, "array"); // returns an un-linked array value from object
    2. var vBoolean = funObjectEntryCopy(objData.vBoolean, "bool"); // returns an un-linked boolean value from object
    3. var vInteger = funObjectEntryCopy(objData.vInteger, "int"); // returns an un-linked integer value from object
    4. var vString = funObjectEntryCopy(objData.vString, "string"); // returns an un-linked string value from object
    5. var vDefault = funObjectEntryCopy(objData.vString); // returns an un-linked string value from object, if no type parameter is set
     
    Last edited: Feb 9, 2015
  8. SongSing

    SongSing KILLL

    Joined:
    Jan 2, 2013
    Messages:
    641
    Likes Received:
    191
    PO Trainer Name:
    SongSing
    Code (javascript):
    1. function deepCopy(obj) {
    2.    return JSON.parse(JSON.stringify(obj));
    3. }
    should work for p much anything, less complicated, use try catch if you want error catchin
    also you should use === instead of == in general probaly
    also you shouldnt prefix every var with v
     
  9. Nightfall Alicorn

    Nightfall Alicorn Left Pokémon Online, most likely not coming back.

    Joined:
    Oct 15, 2013
    Messages:
    491
    Likes Received:
    171
    PO Trainer Name:
    Nightmare Moon
    The v is just a self-taught coding rule I have since I once had trouble with script time ago and it was just because one variable was actually a built-in function. Just adds error proof to code.

    I'm not sure about the == and === thing though but I thought === causes more issues with type error giving wrong comparison.

    Won't that method just parse between all the values inside the object though? Example:
    Code (JavaScript):
    1. var vPokemonName = function deepCopy(objData.vPokemonName);
    2. print(vPokemonName);
    3. // prints Pikachu,Eletric,25
    Sorry. I'm still learning how advanced scripts work. Will the typeof return correctly with this method?
     
  10. SongSing

    SongSing KILLL

    Joined:
    Jan 2, 2013
    Messages:
    641
    Likes Received:
    191
    PO Trainer Name:
    SongSing
    Code (javascript):
    1. var vPokemonName = function deepCopy(objData).vPokemonName;
    2. print(vPokemonName);
    3. // prints Pikachu
    the deepCopy(objData) will return an array/object/whatever, so you can just use its property

    and both the vVar naming convention and the == are fallbacks, yea
    theyre like training wheels, if you intend to get srs tho you should drop them

    just have specific names for vars and you shouldnt run into the built-in function problem, and make sure your types are correct so === wont mess up. good var names are easier to read and === is faster then ==

    you dont have to, of course, but just somethin to think about
    gl with your botmaking : )
     
    Nightfall Alicorn likes this.
  11. Nightfall Alicorn

    Nightfall Alicorn Left Pokémon Online, most likely not coming back.

    Joined:
    Oct 15, 2013
    Messages:
    491
    Likes Received:
    171
    PO Trainer Name:
    Nightmare Moon
    Works perfectly. Thanks SongSing. I thought Crystal meant copy the full object, didn't know it would work for object values on its own. I'll try using === more.
     
  12. Nightfall Alicorn

    Nightfall Alicorn Left Pokémon Online, most likely not coming back.

    Joined:
    Oct 15, 2013
    Messages:
    491
    Likes Received:
    171
    PO Trainer Name:
    Nightmare Moon
    I've been testing around and found that these two both provide the same outputs:
    Code (JavaScript):
    1. var vEntryOne = funDeepCopyObject(objDebug.entryOne);
    2. // and
    3. var vEntryOne = funDeepCopyObject(objDebug).entryOne;
    I don't know if there any positive and negative between them though.
     
  13. IceKirby

    IceKirby A.K.A. RiceKirby

    Joined:
    Apr 26, 2011
    Messages:
    2,176
    Likes Received:
    635
    PO Trainer Name:
    RiceKirby
    On the first line, you are making a copy of the entryOne object, while on the second line you are making a copy of the objDebug object and then reading an object called "entryOne" within the copy of objDebug.

    The result is indeed the same, but the first one should be faster since you are not making a copy of the entire objDebug, only the entryOne, while the second line copies the whole objDebug and then picks the entryOne from that.
     
  14. Crystal Moogle

    Crystal Moogle Ayaya~

    Joined:
    Jul 19, 2010
    Messages:
    3,204
    Likes Received:
    530
    PO Trainer Name:
    Hanako
    Yeah I guess I wasn't clear. The first one is essentially what I was getting at.
     
  15. Nightfall Alicorn

    Nightfall Alicorn Left Pokémon Online, most likely not coming back.

    Joined:
    Oct 15, 2013
    Messages:
    491
    Likes Received:
    171
    PO Trainer Name:
    Nightmare Moon
    Thanks for all your help, guys. I hope I can make something good from this new knowledge that help the server.
     
  16. SongSing

    SongSing KILLL

    Joined:
    Jan 2, 2013
    Messages:
    641
    Likes Received:
    191
    PO Trainer Name:
    SongSing
    the first one is somewhat faster but not as safe (some extension functions will modify the source i think, might be thinking of another language tho)
    but yea