How to Pass the This Context to a Function

How do I pass the this context to a function?

Javascripts .call() and .apply() methods allow you to set the context for a function.

var myfunc = function(){
alert(this.name);
};

var obj_a = {
name: "FOO"
};

var obj_b = {
name: "BAR!!"
};

Now you can call:

myfunc.call(obj_a);

Which would alert FOO. The other way around, passing obj_b would alert BAR!!. The difference between .call() and .apply() is that .call() takes a comma separated list if you're passing arguments to your function and .apply() needs an array.

myfunc.call(obj_a, 1, 2, 3);
myfunc.apply(obj_a, [1, 2, 3]);

Therefore, you can easily write a function hook by using the apply() method. For instance, we want to add a feature to jQuerys .css() method. We can store the original function reference, overwrite the function with custom code and call the stored function.

var _css = $.fn.css;
$.fn.css = function(){
alert('hooked!');
_css.apply(this, arguments);
};

Since the magic arguments object is an array like object, we can just pass it to apply(). That way we guarantee, that all parameters are passed through to the original function.

Passing a function with React Context API to child component nested deep in the tree

Maybe something like that?

<Context.Provider
value={{
state: this.state,
onSortClient: this.onSortClient,
}}
>
{this.props.children}
</Context.Provider>

So, value.state will be your state, value.onSortClient will be your function.

How to pass context to a different view function?(Django)

You can pass the id of the object into the url by altering the following:

template

<td data-label="Quote">
<a href="{% url 'bypass_link' i.id %}" target="_blank">{{ i.link }}</a>
</td>

urls.py

from django.conf.urls import url 

url(r'^bypass_link/(?P<pk>\d+)/$', views.bypass_link, name="bypass_link"),

Then in your function you need to find the same model instance and then extract the link.

def bypass_link(request, pk=None):
instance = fields.objects.get(pk=pk)
print(instance.link) # now you have your link

Now you have access to the link via instance.link

How to pass a function in React's Context?

You aren't using context correctly. You need to render the Provider and wrap it in the hierarchy

export class CharacterProvider extends Component {
constructor(props) {
super(props);

this.state = {
name: "",
...
getCharacter: this.getCharacter(),
}
}

getCharacter = (id) => {
console.log("Getting the character...")
CharacterDataService.getCharacterById(id)
.then(
response => {
console.log(response);
this.setState({
name: response.data.username,
...
});
}
)
render() {
return (
<CharacterContext.Provider value={this.state}>{children}</CharacterContext.Provider>
)
}
}

export const CharacterConsumer = CharacterContext.Consumer

Not you render this CharacterProvider in the hierarchy like

return (
<CharacterProvider>
<Loader/>
</CharacterProvider>
)

Now you need to specify the contextTypes for Loader and use the function from this.context

export default class Loader extends React.Component { 
static contextTypes = CharacterContext
constructor(props) {
super(props);
this.state = {
names: [/* filled by an API call */]
}
....

render() {
return (
<div className="row mt-3">
<div className="col"></div>
{
Object.values(this.state.names).map( (name) => {
return(
<div className="col-1" key={name}>

<button className="btn btn-info" onClick={() =>
this.context.getCharacter(Object.keys(this.state.names).find(key => this.state.names[key] === name))} key={name}>
{name}
</button>
</div>
)})
}
<div className="col"></div>

</div>
)
}
}

Can I pass this as a parameter to another function in javascript

The javascript functions call() and apply() are both for precisely for the purpose of calling a function within a context.

function sum() { 
return this.num1 + this.num2;
}

function callSum(num1, num2) {
this.num1 = num1
this.num2 = num2
return sum.call(this); //call sum() in the context of this
}

alert(callSum(10, 15));

function applySum(num1, num2) {
this.num1 = num1
this.num2 = num2
return sum.apply(this); //call sum() in the context of this
}

alert(applySum(30, 45));

jsfiddle example link

Now in the sum() function the this keyword had the same context as it does in the callSum() and applySum() functions.

The difference between call() and apply() is that apply's second parameter is either an array of parameters to pass or an arguments object.

How do I pass the this context into an event handler?

The old/traditional way:

Capture this in a variable:

this.initialize = function(selector) {
var that = this;
$('span#banner1-nav').click(function(event) {
that._onClickNavigation(event);
});
}

You could also assign this to a variable e.g. instance:

function ScrollBanner() {
var instance = this;
// ...
}

and refer to instance instead of this in all the calls.

The overall idea is to store this in a variable in a higher scope.


The ECMAScript5 way:

ECMAScript5 introduces a new property of functions: .bind(). MDC's documentation shows an implementation for browsers that don't support it. With it you can bind a certain context to a function:

this.initialize = function(selector) {
$('span#banner1-nav').click(this._onClickNavigation.bind(this));
}

but behind the scenes it is doing the same thing. The advantage is that you make use of built-in functionality in browser that support is.

Note that this is different from apply or call. Both of these set the context and execute the function, whereas bind only sets the context without executing the function.


The jQuery way:

jQuery provides a method $.proxy() that is doing the same:

$('span#banner1-nav').click($.proxy(this._onClickNavigation, this));

Best way to pass context

Its an accepted practice in go to pass context from function to function. Normally, the first parameter of every function if context type. I have seen that whenever a context is passed down and has some use-case with in the method scope, a new context is created from parent context.

How to pass context to anonymous function?

The accepted answer seems somewhat outdated. Assuming you're operating on a relatively modern browser, you can use Function.prototype.bind in vanilla javascript. Alternatively, if you are using underscore or jQuery, you can use _.bind or $.proxy respectively (which will fallback to call/apply if necessary).

Here is a simple demonstration of these three options:

// simple function that takes another function
// as its parameter and then executes it.
function execute_param(func) {
func();
}

// dummy object. providing an alternative context.
obj = {};
obj.data = 10;

// no context provided
// outputs 'Window'
execute_param(function(){
console.log(this);
});

// context provided by js - Function.prototype.bind
// src: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind
// outputs 'Object { data=10 }''
execute_param(function(){
console.log(this);
}.bind(obj));

// context provided by underscore - _.bind
// src: http://underscorejs.org/#bind
// outputs 'Object { data=10 }'
execute_param(_.bind(function(){
console.log(this);
},obj));

// context provided by jQuery - $.proxy
// src: http://api.jquery.com/jQuery.proxy/
// outputs 'Object { data=10 }'
execute_param($.proxy(function(){
console.log(this);
},obj));

You can find the code in a jsfiddle here: http://jsfiddle.net/yMm6t/1/ (note: ensure that the developer console is open, or you won't see any output)



Related Topics



Leave a reply



Submit