This question already has answers here:
JavaScript function binding (this keyword) is lost after assignment
(5 answers)
Closed 5 years ago.
firefox (v52.0), jquery
this works:
// example 1
$('html').find('body')
this works:
// example 2
var h
h=$('html')
h.find('body')
This doesn't work:
// example 3
var f
f=$('html').find
f('body')
I get
Error: Permission denied to access property "ownerDocument"
why?
but this works:
// example 4
var a
a = x => $('html').find(x)
a('body')
Example 3 doesn't work because find is called on the global context when you assign it to f. If you use call and pass in a valid jQuery object as the context, the code works. Try this
var f = $('html').find;
console.log(f.call($('html'), 'body').length)
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
Also, example 4 works because a can be translated to the following code, if written without an arrow function.
var a = function(x) {
return $('html').find(x);
};
It's just example 1, but with a wrapper function in order to take a parameter
No, jQuery is not functional
By looking at jQuery core source code:
https://github.com/jquery/jquery/blob/master/src/core.js#L51
You could see it hold state in this.
In f=$('html').find, the this of f is changed and no longer the this holding $('html') state
--
In this case, you are just proxy the method call. The this of find no change.
var a
a x => $('html').find(x)
a('body')
Related
This question already has answers here:
How to execute a JavaScript function when I have its name as a string
(36 answers)
Closed 2 years ago.
My problem is simple and I couldn't find the proper answer in this forum. My bad...
I want to do that :
const dataReceived = foo;
foo(state);
How can I do that?
I read it is better to avoid eval, and I couldn't get success with new Function.
Thanks for your help!
EDIT
Thanks for your answers.
I work with React.
In my reducer, I have a create_item case.
I can reach action.category, that can be the word 'currency' or 'country'.
What I want to do is to launch either the method createCurrency or createCountry according what is inside action.category.
That's why I tried to join 'create' and 'action.category' to create a dynamic function name.
But it seems to be a poor idea...
The simplest approach is to create an object which contains an entry where:
the key is a string
the value is a function.
Example:
const myObject = {
myFunction: () => { [... DO SOMETHING...] }
}
Subsequently you will be able to invoke the function, using:
myObject.myFunction();
The above becomes more powerful when you use brackets notation.
Example:
const myString = 'myFunction';
myObject[myString]();
This question already has answers here:
How to access the correct `this` inside a callback
(13 answers)
Closed 3 years ago.
Edit:
The question referred to as the duplicate doesn't really answer why arrow functions shouldn't be used to access a non-lexical this. It just answers that arrow functions automatically bind this. My situation is that using an arrow function rather than a normal function cause me to lose the correct reference of this. If you need this outside of the current scope, use a normal function.
I've searched around for a solution to my problem with no luck. Even if I was pointed in the right direction as to what I needed to do would be awesome! My problem essentially is that this.Favkey is undefined here:
const setFavorite = val => {
console.log(this);
this.Favorite = val;
AsyncStorage.setItem(this.Favkey, JSON.stringify(val));
};
This function is getting assigned to a particular object like so:
for (const obj of objArray) {
obj.Favkey = `c${obj['-id=']}`;
obj.Favorite = await getFavorite(obj.Favkey);
obj.SetFavorite = setFavorite;
}
And then I am calling this later on a button:
onPress={val => props.myObj.SetFavorite(val)}
In the first block of code, I want this to be the specific obj that I am attempting to enclose the function on. But this.Favkey in setFavorite is undefined. What is printed out instead on console.log(this) is what I think is the whole prototype of Object. So I'm not quite sure what I'm doing wrong here.
Don't use an arrow function - it loses the binding to this which is what you're trying to access. Just use a normal function:
const setFavorite = function(val) {...};
This question already has answers here:
Execute JavaScript code stored as a string
(22 answers)
Closed 8 months ago.
Is it possible to define a function run that acts like this?
a = run('var x = 100;')
b = run('console.log(x);') // prints 100
c = run('y = 1;')
d = run('console.log(y);') // prints 1
I tried several ways, using apply and passing the same context, binding a context to a function, returning a closure with a recursive call etc. but I can't seem to get anything to work.
Yeah, as MyLibrary says, you probably want eval, if you really want to do this. So:
var run = eval;
a = run('var x = 100;')
b = run('console.log(x);') // prints 100
c = run('y = 1;')
d = run('console.log(y);') // prints 1
would seem to work.
JavaScript allows assigning functions to variables, so you can set the run variable to eval. As far as eval, you may want to learn about it and as you can see from comments, its use in normal function creation is often discouraged.
Are you referring to eval function?
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/eval
This question already has answers here:
How does the "this" keyword work, and when should it be used?
(22 answers)
Closed 6 years ago.
Suppose I have an object:
var o = {
prop: 3,
method: function() {return this.prop}
}
I was expecting this
(o.method)()
to return undefined, however it returned 3 meaning that this is set to o inside method. Why is it so? If you evaluate (o.method) separately, it evaluates to a standalone function, so I expected this to reference global object. Why, for example, the difference exists here:
(o.method)() vs (o.method || true)()
I know that o.method() will use o as context, the question is specifically about accessing the function first like this (o.method) and then calling it.
That's just how JavaScript's rules work. Unless you do some contortions, this usually means the thing before the . when you access the method prior to calling it. In this case, that's o.
The following statements are identical:
(o.method)();
o.method();
o.method.call(o);
o["method"]();
However, if you put the method on something else, it'll take on the meaning of the thing it's on:
var p = {prop: 42, method: o.method};
p.method(); // returns 42
var method = o.method;
var prop = 13;
method(); // returns 13
Note: As JavaScript grew to be much more than it was originally designed for, people realized that this probably wasn't the most intuitive way for this to work, so in ES6 if you use "Arrow Functions" (aka Lambda Functions) it won't rebind this.
This question already has an answer here:
Accessing a JSON property (String) using a variable
(1 answer)
Closed 8 years ago.
I want to use a string as a JSON property in JavaScript.
var knights = {
'phrases': 'Ni!'
};
var x = 'phrases';
console.log(knights.x); // Doesn't log "Ni!"
When I run this code, it obviously doesn't work because it interprets "x" and not the contents of the variable "x".
The full code in context on pastebin: http://pastebin.com/bMQJ9EDf
Is there an easy solution to this?
knights.x looks for a property named x. You want knights[x], which is equivalent to knights['phrases'] == knights.phrases.
Full code (fixing a couple of typos in your example):
var knights = {
"phrases": "Ni!"
};
var x = 'phrases';
console.log(knights[x]); // logs Ni!
Try this to access using variables having string values
kinghts[x]
Basically this is trick
kinghts[x]==knighted["phrases"]==knighted.phrases.
knights.x will get a key named x, So it'll return undefined here.
knights.x is the same as knights['x'] - retrieving a property under the key x. It's not accessing the variable x and substituting in the value. Instead, you want knights[x] which is the equivalent of knights['phrases']