This question already has answers here:
Is it possible to achieve dynamic scoping in JavaScript without resorting to eval?
(7 answers)
Closed 5 years ago.
For example. I have this code:
export const mergeWrapper = function(aFunction, meta) {
return aFunction;
};
function exampleFunction(temp) {
console.log(temp);
// can print here. without changing exampleFunction method signature.
// in this case should be 'stackoverflow'
console.log(meta);
}
mergeWrapper(exampleFunction, 'stackoverflow')('hello');
I want to do "something" in mergeWrapper. so that, inside aFunction, I can call meta. I have tried something such as:
export const mergeWrapper = function(aFunction, meta) {
aFunction.bind(this);
return aFunction;
};
But it doesn't work. How can I do this.
My idea because I can write some sort of this function using currying. for example:
export const wrapperFunction = function(meta) {
return function(temp) {
console.log(temp);
console.log(meta);
}
}
wrapperFunction('StackOverFlow')('hello');
But written like this will make me write wrapper for all functions. So I want to write a helper.
Thanks
You can do
const mergeWrapper = function(aFunction, meta) {
return aFunction.bind(null, meta);
};
function exampleFunction(meta, temp) {
console.log(temp);
// can print here. without changing exampleFunction method signature.
// in this case should be 'stackoverflow'
console.log(meta);
}
let func = mergeWrapper(exampleFunction, 'stackoverflow');
func('temp');
func('temp2');
Where you have binded meta as the first argument, and all calls would get that value of meta
Related
This question already has answers here:
What's the difference between passing by reference vs. passing by value?
(18 answers)
Closed last year.
EDIT 2: Why has this very specific question been marked as a duplicate of this very conceptual one: What's the difference between passing by reference vs. passing by value?. If someone else had the same question as me, they wouldn't end up with this one on Google by searching for it and - even if they did - it wouldn't answer their question.
EDIT: Thanks everyone for your help so far. Pretty difficult stuff to understand from my point of view. The reason I'm doing this is that I've set up a function which I'm calling multiple times and in which I define a variable (a unique one with each call). I need to be able to refer back to each unique variable afterwards. Here is my actual attempted code below. What would the right way to do this be?
let newSeq1
let newSeq2
function sequenceClip(sample, length, sequenceVariable) {
let currentPosition = Tone.Transport.position
let whenToStart
if (currentPosition === '0:0:0') {
whenToStart = '0:0:0'
} else {
const barToStartOn = +currentPosition.slice(0, currentPosition.indexOf(':'))
whenToStart = `${barToStartOn + 1}:0:0`
}
sequenceVariable = new Tone.Sequence((time, note) => {
sampler.triggerAttackRelease(note, '4m', time)
}, [sample], length).start(whenToStart);
}
loop1.addEventListener('mousedown', () => {
sequenceClip("C3", '1m', newSeq1)
})
loop2.addEventListener('mousedown', () => {
sequenceClip("C#3", '4m', newSeq2)
})
How do I pass a variable into a function in Javascript to be assigned a value. E.g.:
Why does the variable not get assigned the value 5? And what's the way around this?
let a
function defineVariable(var2beDefined) {
var2beDefined = 5
}
defineVariable(a)
console.log(a === 5)
You would typically write an initializer function that returns a value and assign that return value to the relevant global variable. For example:
let newSeq1
let newSeq2
function sequenceClip(sample, length, sequenceVariable) {
let currentPosition = Tone.Transport.position
let whenToStart
if (currentPosition === '0:0:0') {
whenToStart = '0:0:0'
} else {
const barToStartOn = +currentPosition.slice(0, currentPosition.indexOf(':'))
whenToStart = `${barToStartOn + 1}:0:0`
}
return new Tone.Sequence((time, note) => {
sampler.triggerAttackRelease(note, '4m', time)
}, [sample], length).start(whenToStart);
}
loop1.addEventListener('mousedown', () => {
newSeq1 = sequenceClip("C3", '1m')
})
loop2.addEventListener('mousedown', () => {
newSeq2 = sequenceClip("C#3", '4m')
})
Note that both newSeq1 and newSeq2 will be undefined until the first mousedown/mouseup events.
Reassigning an identifier, by itself, never has any side-effects (in most circumstances) - the only change resulting from someIdentifier = someNewValue will be when other parts of the code reference that same someIdentifier.
If you want to pass in something to be assigned to, pass in a function which, when called, assigns to the outer variable.
let a;
function defineVariable(callback) {
callback(5);
}
defineVariable(newVal => a = newVal);
console.log(a === 5)
The only time that assigning to an identifier will have side effects is if:
Inside a function with a simple argument list, you reassign one of the parameters (in which case the arguments object will be changed as well)
You're using ES6 modules, and you reassign an identifier that's being exported, in which case other modules that import it will see the change as well
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 2 years ago.
Improve this question
Example :
Creating function
const isElementLoaded = () => {
//Logic
return true;
}
Calling function using this.isElementLoaded :
if (this.isElementLoaded)
{
//output true
}
If you don't want to use (), you need to make it an accessor property. (The only other way to call it without () is to use it as a tag function on a tagged template literal, which doesn't seem relevant to what you're doing. :-) )
In a class, you'd do that like this:
class Example {
get isElementLoaded() {
return /*...appropriate value...*/;
}
}
In an object literal, it's basically the same:
const obj = {
get isElementLoaded() {
return /*...appropriate value...*/;
}
};
In either case, TypeScript should be able to infer the return type from your return statement, but if necessary add the annotation, e.g.:
class Example {
get isElementLoaded(): boolean {
return /*...appropriate value...*/;
}
}
If you want to add an accessor to an object after it's created, you use defineProperty:
Object.defineProperty(obj, "isElementLoaded", {
get() {
return /*...appropriate value...*/;
},
// flags here if appropriate; they default to `false` if omitted
});
You'll need to be sure the type information for the object includes the accessor (perhaps as an optional property).
Either you use a function and then you need to use () to call the function (that's the TypeScript / JavaScript syntax):
const isElementLoaded = () => {
//Logic
return true;
}
// in a function:
if (this.isElementLoaded()) {
//output true
}
Or, you can use a property on your class with a getter:
get isElementLoaded() {
//Logic
return true;
}
// in a function
if (this.isElementLoaded) {
//output true
}
tl;dr: use this.isElementLoaded()
You are actually not calling the function you created there. You are using arrow notation to create a function, you could do the same with
function isElementLoaded(...){...}
which would it make more clear maybe that you have to call it to actually do something. By just calling the name of the function you reference to the function body - but that is not progressed in any way.
Here's a quick try-out example: https://jsbin.com/kekifugoqe/edit?js,console
Hit 'run' and you see the difference in the output.
This question already has answers here:
Javascript Object destructuring and default parameters combined
(3 answers)
Closed 2 years ago.
Just looking over a cool tutorial and there was a notation that I didn't completely understand and having a hell of a time trying to google it.
async function mapEffect({ leafletElement: map } = {}) {
let response;
try {
response = await axios.get(‘https://corona.lmao.ninja/countries’);
} catch(e) {
console.log(`Failed to fetch countries: ${e.message}`, e);
return;
}
// this next line here is the one confusing me:
const { data = [] } = response;
}
Reading on, it appears that data is just an array - any reason it is written like this? Can anyone explain in layman's terms why you would write something this way? I never stop learning... Thank you!
const { data = [] } = response;
is equal to
// [] is default value if response.data is empty
const data = response.data || [];
What that piece of code is doing is destructuring an object.
Destructuring lets you bind variables to different properties of an object. When you specify the property being bound, it will then be followed by the variable you are binding its value to.
Here is a basic example:
const { foo, bar } = { foo: "hello", bar: "world" };
console.log(foo);
console.log(bar);
//1st letter
console.log(foo[0]);
console.log(bar[0]);
In your case it has a default value as fallback ( [] an array in case your response comes empty)
You can read more about it here
This question already has an answer here:
How to destructure option argument with all default values in ES6?
(1 answer)
Closed 3 years ago.
I have a problem with referencing to data with this while trying to declare default parameters combined with destructuring. Anyone knows how to do it?
activated () {
this.fillData()
},
data () {
return {
chartData: {
distributionInitialData: {
// data here
}
}
}
},
methods: {
fillData ({
must = this.chartData.distributionInitialData,
nice = this.chartData.distributionInitialData
}) {
// do something
// function doesn't even get here because it gets error:
// TypeError: Cannot read property 'must' of undefined
// at VueComponent.fillData (Component.vue?4e6a:230)
// at VueComponent.activated (Component.vue?4e6a:123)
}
}
You need to set the default value for the parameter(Object), but not to its properties.
methods: {
fillData ({must, nice} = {
must: this.chartData.distributionInitialData,
nice: this.chartData.distributionInitialData
}) {
// do something
}
}
Updated by Bergi's advice.
methods: {
fillData ({
must: this.chartData.distributionInitialData,
nice: this.chartData.distributionInitialData
} = {}) {
// do something
}
}
FYI, here is a simple codepen.
You can do.
fillData ({ must, nice}) {
must = must || this.chartData.distributionInitialData
nice = nice || this.chartData.distributionInitialData
// do something
}
So the issue has to do with how Vue binds the methods to the component as it is created. The function definition does not have access to the instance, but inside of it you may use this.
The easiest solution would be to do an immediate check for undefined and set based on the desired default.
fillData({ must, nice }) {
if (must === undefined) must = this.chartData.distributionInitialData;
if (nice === undefined) nice = this.chartData.distributionInitialData;
// any other code here
}
You might also try playing around with arrow functions to see if it fixes this, since that was introduced to be bound to this in a more concrete way. Perhaps something like this:
fillData = ({
must = this.chartData.distributionInitialData,
nice = this.chartData.distributionInitialData
}) => {
// any other code here
}
This question already has answers here:
Accessing an object property with a dynamically-computed name
(19 answers)
Closed 3 years ago.
i need to return this.
GetBooking = function (parameter) {
return Booking.Title[0].parameter;
}
GetPages = function () {
return GetBooking(pages)
}
GetNumber = function () {
return GetBooking(number)
}
booking is a object of arrays, is possible?
If I understand correctly, when doing GetBooking(pages) you expect to get in return Booking.Title[0].pages, meaning GetBooking() function is supposed to be like a middleman to decide which property you want to get from Booking.Title[0].
If I'm correct, then you almost had it right. What will happen in your code is, for example if number was 7, it would look for a property named 7 inside Booking.Title[0].
What you really want to do is this: return Booking.Title[0][parameter], and parameter has to be a string value representing the property you're looking for, meaning you also need to change the rest of the code which would ultimately look like this:
GetBooking = function (parameter) {
return Booking.Title[0][parameter];
}
GetPages = function () {
return GetBooking("pages") ;
}
GetNumber = function () {
return GetBooking("number") ;
}
This will take the string in parameter and look for a property that matches that string inside Booking.Title[0], and return its value.