I'm attempting my first forray into jQuery. I'm trying to acheive the following, though I'm not sure of the terminology so will try to explain with an example using a kind of C#/pseudocode syntax.
Say I want an (anonymous) object as parameter, looking something like:
elemParameter {
elemId,
arg1,
optionalArg2
}
and I want to pass an array/collection of these objects into my function
$(document).ready(function() {
$.myFunction(
new { Id = "div1", Color = "blue", Animal = "dog" },
new { Id = "div3", Color = "green" },
new { Id = "div4", Color = "orange", Animal = "horse" }
);
}
and then in my function, I need to access each object of the collection, something like:
(function($) {
$.myFunction(var elemParams) {
foreach (param in elemParams) {
$('#' + param.Id).onclick = function() {
this.css('background-color', param.Color);
alert(param.Animal ?? 'no animal specified');
}
}
}
}
Can someone give me a few pointers to the correct syntax for passing parameters this way? Or suggest a better way of acheiving the same if this isn't the correct way to go about things in javascript.
Your syntax is just a bit off, it would look something like this:
$(function() {
function myFunction() {
$.each(arguments, function(i, arg) {
$('#' + arg.Id).click(function() {
$(this).css('background-color', arg.Color);
alert(arg.Animal || 'no animal specified');
});
});
}
myFunction({ Id: "div1", Color: "blue", Animal: "dog" },
{ Id: "div3", Color: "green" },
{ Id: "div4", Color: "orange", Animal: "horse" });
});
You can try a demo here, the syntax style is called JavaScript object literal notation, that's what you're googling for when looking for more info around this :)
Alternatively you can pass the objects in as an array if you want other arguments in addition to these, rather than using arguments directly.
You're looking for "object literal notation." It looks like this:
{
propertyName: propertyValue,
propertyName2: propertyValue2
}
You don't use the new keyword with them, they're just a literal construct like strings ("foo") or numbers (42). Similarly, you have array literals:
["one", "two", "three"]
Here's your example updated:
$(document).ready(function() {
$.myFunction(
// <== Start an array literal with [
[
// <== Colons rather than equal signs
{ Id: "div1", Color: "blue", Animal: "dog" },
{ Id: "div3", Color: "green" },
{ Id: "div4", Color: "orange", Animal: "horse" }
// End the array literal with ]
]
);
}
Note that it's important not to have a trailing comma in either an object or array literal, e.g.
["one", "two", "three", ]
^--- Don't do that
{foo: "bar", x: 27, }
^------- Or that
The question of whether they were valid was unclear (it's clear now as of the recent 5th edition) and IE (at least) chokes on them.
Off-topic, but typically property names in JavaScript code are in camelCase and start with a lower case letter (so, for instance, animal rather than Animal). This is purely style, however.
Related
I am modifying JSON files/Javascript object using Pinch library: https://github.com/Baggz/Pinch
In this example, pinch() with regex parameter /id/ modifies ALL the id values to 321.
What I want to do is be able to change the value of all ids but only for a specific "Requestor", based on a parameter (requestorToChange). Let's say "RequestorX". How do I write the regex for it?
var sample = {
"RequestorX":
[{
user: {
id: '123'
},
request: {
id: '456'
},
book: {
id: '789'
}
}],
"RequestorY":
[{
user: {
id: '111'
},
request: {
id: '222'
},
book: {
id: '333'
}
}]
};
const requestorToChange = 'RequestorX'
pinch(sample, /id/, function(path, key, value) {
return '321';
});
console.log(JSON.stringify(sample))
I know that one option is to just do:
pinch(sample['RequestorX'], /id/, function(path, key, value) {
return '321';
});
But I need to be able to do it via the regex field since in reality, I will be manipulating deeply nested JSON files.
The explanation on the GitHub page is a bit sparse, but basically you start with the dot notation replacement style and replace the variable parts with regex patterns whilst adhering to the rules of JS regular expressions.
So, in your case, a dot notation pattern 'RequestorX[0].user.id'
becomes a regex like /RequestorX\[0\]\.(user|request|book)\.id/
Somes notes:
first we have to escape the square brackets because those have special meaning in regex
next, we also have to escape the . to use it as dot notation symbol
we use a group with alternations to replace the id on all of them
I tried to use new RegExp instead of the /../ notation to create a regex Object to add your constant to the pattern, unfortunately only the first item is replaced in this case, probably a bug...
pinch(sample, new RegExp(requestorToChange +'\[0\]\.(user|request|book)\.id'), '321');
Sample code (the SO code snippet outputs some extra gibberish about RequestorY, ignore it)
var sample = {
"RequestorX": [
{
"user": {
"id": "123"
},
"request": {
"id": "456"
},
"book": {
"id": "789"
}
}
],
"RequestorY": [
{
"user": {
"id": "123"
},
"request": {
"id": "456"
},
"book": {
"id": "789"
}
}
]
}
const requestorToChange = 'RequestorX';
//var result = pinch(sample, 'RequestorX[0].user.id', '321'); //replace the user id of RequestorX with dot notation
var result = pinch(sample, /RequestorX\[0\]\.(user|request|book)\.id/, '321');
//var result = pinch(sample, new RegExp(requestorToChange +'\[0\]\.(user|request|book)\.id'), '321');
console.log(JSON.stringify(result));
<script src="https://cdn.jsdelivr.net/npm/pinch#0.1.3/src/pinch.js"></script>
Alas, JSON + regex sounds a bit weird but the tool looks legit.
I have a problem with code I am supposed to work with. I found a syntax I am not familiar with and I have trouble googling the documentation:
export const Something = class Something {
constructor(someObject = {}) {
this.someObject = {...Something.someObjectDefaultAsStaticMethod,...someThing};
};
// The rest of the class
};
I have problems understanding what the three dots (...) in front of the parameter do. And "dots in parameter javascript" is a bad search term. Can someone help me, maybe tell me what this syntax is actually called or just directly link me to documentation?
That is not ES6 but has only been added in ECMAScript 2018.
It is called "Object Rest/Spread Properties" and is part of the Spread Syntax.
... (three dots in Javascript) is called the Spread Syntax or Spread Operator. This allows an iterable such as an array expression or string to be expanded or an object expression to be expanded wherever placed.
I want to list down the mostly used practical Use Cases of the Spread Syntax (Spread Operator). The following has been explained with examples in this stackoverflow answer.
Combine Arrays (Concatenate Arrays)
Copying Arrays
Calling Functions without Apply
Destructuring Arrays
Function Arguments as Rest Parameters
Using Math Functions
Combining Two Objects
Separate a String into Separate Characters
The [...something] is the spread operator. It in essence allows for an array or string to be expanded. You will see it used often in React, but has many other use cases.
MDN has great documentation on the spread operator:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_operator
You can use "..." in an object. In this example below, "...data" gets 'name: "John", age: 24':
const data= { name: "John", age: 24 };
const newData = {
...data, // Here
sex: "Male"
}
console.log(newData);
This is the result:
{ name: "John", age: 24, sex: "Male" }
This is other example with "...data[key]" to add "id" to each object in an array:
const data = [
{ name: "John", age: 24 },
{ name: "Marry", age: 18 },
{ name: "Tom", age: 15 },
]
const newData = [];
for(const key in data) {
const obj = {
id: Number(key),
...data[key] // Here
}
newData.push(obj);
}
console.log(newData);
This is the result:
[
{ id: 0, name: "John", age: 24 },
{ id: 1, name: 'Marry', age: 18 },
{ id: 2, name: 'Tom', age: 15 }
]
Context: One of the use cases is to do a "copy", but you should take care of this particular "by reference" behavior when working with sub-properties.
Finding: Take care that sub-properties are NOT passed by value, but by reference. In other words, only first level properties are passed as a copy "by value". See the example:
sourcePerson = { name: 'John', colors: ["red", "blue"] }
targetPerson = { ...sourcePerson }
console.log("Target person result:\n", JSON.stringify(targetPerson), "\n\n") //it seems a copy, but...
console.log("Let's update the name source value:\n")
sourcePerson.name = 'Kevin'
console.log("Updated source person:\n", JSON.stringify(sourcePerson), "\n")
console.log("Target person is NOT updated, It keeps a copy by value\n")
console.log(JSON.stringify(targetPerson), "\n\n")
//But if you update a sub-property, it has NOT been copied by value
console.log("Let's update a color sub-property:\n")
sourcePerson.colors[0] = "YELLOW"
console.log("Updated source person:\n", JSON.stringify(sourcePerson), "\n")
console.log("Target person is updated BY REFERENCE!\n")
console.log(JSON.stringify(targetPerson)) // it is not a copy, it is a reference!
console.log("\nCONCLUSION: ... spread syntax make a copy 'by value' for first level properties, but 'by reference' for sub-properties, so take care!\n")
I'm currently working on a small application where I have to loop through an enormous array of objects. What would be the most efficient method to perform this?
var array = [
{
id: "1",
name: "Alpha"
},
{
id: "2",
name: "Beta"
},
...
];
I'd like to get each object where name equals "Alpha". I'm currently using a simple if statement to filter the objects with a different name value out, but I wonder if there's a more efficient way to do this, performance-wise.
It's worth to mention that I'll push the matching results into a new array.
No, there is no more efficient way.
The alternative is to build and maintain some kind of internal data structure which allows you to find the desired elements faster. As usual, the trade off is between the work involved in maintaining such a structure vs the time it saves you.
I don't have any way about which I would know it's more effective.
But if you had your objects ordered by name you could stop your search imideatly upon reaching an object whose name is not equal to "Alpha".
To find the first object you're looking for you can use binary search and from this Object you go up and down until at both ends you reach an object which isn't named "Alpha" or the end of array.
This is only a way of optimizing and will require time to sort the array and also will take more time when adding an element.
There's a JavaScript function exactly for this kind of task. Filter
From the Docs
The filter() method creates a new array with all elements that pass the test implemented by the provided function.
Here is a small example by code for getting all element from array which has a certain 'name' field:
const arr = [
{name: 'Abc'},
{name: 'Xyz'},
{name: 'Lmn'},
{name: 'Xyz'},
{name: 'Xyz'}
];
let response = findByName('Xyz');
console.log(response);
function findByName (name) {
return arr.filter((element) => {
return element.name = name;
});
}
If you need more than one time a collection with a given name, you could use an object with the names as hashes and have instantly access to the items.
var array = [{ id: "1", name: "Alpha" }, { id: "2", name: "Beta" }, { id: "3", name: "Beta" }, { id: "4", name: "Gamma" }, { id: "5", name: "Beta" }, { id: "2", name: "Alpha" }],
hash = Object.create(null);
array.forEach(function (a) {
if (!hash[a.name]) {
hash[a.name] = [];
}
hash[a.name].push(a);
});
console.log(hash);
.as-console-wrapper { max-height: 100% !important; top: 0; }
I have a problem with code I am supposed to work with. I found a syntax I am not familiar with and I have trouble googling the documentation:
export const Something = class Something {
constructor(someObject = {}) {
this.someObject = {...Something.someObjectDefaultAsStaticMethod,...someThing};
};
// The rest of the class
};
I have problems understanding what the three dots (...) in front of the parameter do. And "dots in parameter javascript" is a bad search term. Can someone help me, maybe tell me what this syntax is actually called or just directly link me to documentation?
That is not ES6 but has only been added in ECMAScript 2018.
It is called "Object Rest/Spread Properties" and is part of the Spread Syntax.
... (three dots in Javascript) is called the Spread Syntax or Spread Operator. This allows an iterable such as an array expression or string to be expanded or an object expression to be expanded wherever placed.
I want to list down the mostly used practical Use Cases of the Spread Syntax (Spread Operator). The following has been explained with examples in this stackoverflow answer.
Combine Arrays (Concatenate Arrays)
Copying Arrays
Calling Functions without Apply
Destructuring Arrays
Function Arguments as Rest Parameters
Using Math Functions
Combining Two Objects
Separate a String into Separate Characters
The [...something] is the spread operator. It in essence allows for an array or string to be expanded. You will see it used often in React, but has many other use cases.
MDN has great documentation on the spread operator:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_operator
You can use "..." in an object. In this example below, "...data" gets 'name: "John", age: 24':
const data= { name: "John", age: 24 };
const newData = {
...data, // Here
sex: "Male"
}
console.log(newData);
This is the result:
{ name: "John", age: 24, sex: "Male" }
This is other example with "...data[key]" to add "id" to each object in an array:
const data = [
{ name: "John", age: 24 },
{ name: "Marry", age: 18 },
{ name: "Tom", age: 15 },
]
const newData = [];
for(const key in data) {
const obj = {
id: Number(key),
...data[key] // Here
}
newData.push(obj);
}
console.log(newData);
This is the result:
[
{ id: 0, name: "John", age: 24 },
{ id: 1, name: 'Marry', age: 18 },
{ id: 2, name: 'Tom', age: 15 }
]
Context: One of the use cases is to do a "copy", but you should take care of this particular "by reference" behavior when working with sub-properties.
Finding: Take care that sub-properties are NOT passed by value, but by reference. In other words, only first level properties are passed as a copy "by value". See the example:
sourcePerson = { name: 'John', colors: ["red", "blue"] }
targetPerson = { ...sourcePerson }
console.log("Target person result:\n", JSON.stringify(targetPerson), "\n\n") //it seems a copy, but...
console.log("Let's update the name source value:\n")
sourcePerson.name = 'Kevin'
console.log("Updated source person:\n", JSON.stringify(sourcePerson), "\n")
console.log("Target person is NOT updated, It keeps a copy by value\n")
console.log(JSON.stringify(targetPerson), "\n\n")
//But if you update a sub-property, it has NOT been copied by value
console.log("Let's update a color sub-property:\n")
sourcePerson.colors[0] = "YELLOW"
console.log("Updated source person:\n", JSON.stringify(sourcePerson), "\n")
console.log("Target person is updated BY REFERENCE!\n")
console.log(JSON.stringify(targetPerson)) // it is not a copy, it is a reference!
console.log("\nCONCLUSION: ... spread syntax make a copy 'by value' for first level properties, but 'by reference' for sub-properties, so take care!\n")
I have some issues to organize my code.
Here is an example of what i would like to do:
var Test = {
old: [
get: function(who, when){
returrn({ subject: "Old test 001", text: "The test 001 was perform by "+who });
},
get: function(who, when){
returrn({ subject: "Old test 002", text: "The "+when+" the test 002 was performed"});
}
],
new: [
//Same thing
]
};
The thing is, we apparently can't do that, so i am wondering which is the way to declare functions in an Array ?
I need to do that because each method get() of the array can return a different message and the message can include the variables passed in parameters at different positions in the text, so i have to declare it explicitly.
I don't do like this:
var Test = {
old: [
one: {
get: function(who, when){
returrn({ subject: "Old test 001", text: "The test 001 was perform by "+who });
},
},
two: {
get: function(who, when){
returrn({ subject: "Old test 002", text: "The "+when+" the test 002 was performed"});
}
}
],
new: [
//Same thing
]
};
Because i need to access the content dynamically, like Test.old[test_id].get("toto", "02/04/2013"). and we unfortunatelly can't index things by numerical values in JSON.
However i'll do it like this is there is nothing better.
So what is the best thing to do in this context ?
Thanks !
The question is vague and confusing, but I can see why your code doesn't work. You're conflating arrays and objects. Array literals look like this:
var myArray = [
"first item",
"second item",
{value: "third item"},
["first/only item in fourth item"],
1,
2,
3.14159,
function(a,b) { return a + b; },
"etc."
];
Items in an array are accessed using push, pop, shift, unshift, and numerical indexes.
Object literal look like this:
var myObject = {
one: "some value",
two: {
value: "object values can be anything"
},
123: 456,
"a million": function (a, b) { return a - b; }
};
Items in an object are access using string indexes.
And finally, do you have a returrn() function declared somewhere? In either case, why not just return your return values?