using bind method with () function javascript - javascript

I have one question, when I use bind with arrow function doesn't work so if there 's anyone can explain it to me.
let username={
email:"test#test",
login:()=>{console.log(this.email);}
};`
when i tap username.login()return undefined also if u tap username.login.bind(username) if there's anyone who can help I will be very thankful.
I m all ears for more info.

Have a read of this from MDN to understand how arrow functions deal with this differently from other functions. This, indeed, was the main reason arrow functions were introduced - they are not primarily about a "nicer" syntax, even though this seems to be how many developers today use them. (And there is nothing wrong with using them that way, but you do absolutely have to be aware of how these functions behave differently.)
As the MDN link explains, the fact that arrow functions "inherit" the this of their enclosing scope is a convenience in many common situations. But, as you have discovered, it also causes problems in cases where you rely on the value of this to be a particular object. Here is a simple demonstration of how the difference arises in your case:
let username1={
email:"test#test",
login:()=>{console.log(this.email);}
};
let username2={
email:"test#test",
login:function(){console.log(this.email);}
};
username1.login(); // logs "undefined"
username2.login(); // works as expected
The reason is because in username2, with the "ordinary" function (not an arrow function) follows the normal rules for what this means inside a function. These are too difficult to go into here (although less difficult than are often thought, and I would well advise understanding what they are) - suffice to say though that the value of this inside a function depends on how the function was called, and that usually, when you call a function as a direct property of an object, as you do with username2.login() here, this will be that object (namely username2).
But with username1.login(), the function is an arrow function, which as the MDN article explains, does not follow these standard rules. Instead the this is adopted from the enclosing scope. Here that's the global scope, not a function scope, so there isn't actually a "real" this to use - and that results in the global (window) object being chosen instead. And since window.email doesn't exist, you get undefined. As proof that this is indeed the global object, recall that window.email is one and the same as a global variable called email. So if we amend the snippet to define a global variable of that name, its value is printed instead:
var email = "this is the global email var";
let username1={
email:"test#test",
login:()=>{console.log(this.email);}
};
let username2={
email:"test#test",
login:function(){console.log(this.email);}
};
username1.login(); // logs global email variable
username2.login(); // works as expected
So that's what's happening here. (Also note that, in real code, the enclosing scope will most often not be global. But it's still quite likely that the this value of the function concerned will be the global object, and even if it isn't, you'll still see undefined printed here unless that particular object happens to have an email property defined.)
The moral of the story is not to use arrow functions for object methods - because any reference to this inside them will not behave as you likely expect. In fact my personal reference is not to use arrow functions at all unless you either need their specific modification of the this rules, or if you need a "throwaway" one-line anonymous function (for example as a function argument to an array's map or filter), in which case the arrow function can make the code more readable. But increased readability and brevity is not the main reason arrow functions exist.

Arrow function is always called with the context in which it was defined. Just use a normal function.
let username={
email:"test#test",
login: function() {console.log(this.email);}
};`
Take a look at ECMAScript 2015 Spec:
Any reference to arguments, super, this, or new.target within an ArrowFunction must resolve to a binding in a lexically enclosing environment. Typically this will be the Function Environment of an immediately enclosing function.

Related

Differences Between Named and Unnamed Anonymous Javascript Functions

Normally, in Javascript, when I want to pass an anonymous/inline function as an argument to another function, I do one of the following.
someFunctionCall(function() {
//...
});
someFunctionCall( () => {
//...
});
However, I've recently inherited a codebase that uses named function as inline arguments, like this
someFunctionCall(function foo() {
//...
});
I've never seen this syntax before. The function still seems to be anonymous -- there's no foo function defined in either the calling or called scope. Is this just a matter of style, or can using a named function (foo above) as an anonymous function change the behavior or state of that program?
This is specifically for a NodeJS (not a browser based program) program, and I'm specifically interested in behavior specific to using functions as parameters. That said information from behavior across platforms and runtimes is welcome.
There are at least three advantages of using named function expressions instead of anonymous function expressions.
Makes debugging easier as the function name shows up in call hierarchy.
The function name is accessible in the inner scope of the function, so it can be used for recursion
The function name itself acts like a self documentation of what the function is doing instead of reading the code.
Using those "named anonymous functions" won't change the behavior but will show the function name in stack traces which is very useful. Also the function gets callable within itself that way.
I'll give an example
Case 1:
var obj = {count: 0, counter: ()=> {this.count+=1;}}
If you do console.log(obj.count) you'll get 0
Case 2:
var obj = {count: 0, counter (){this.count+=1;}}
In 2nd case if you do console.log(obj.count) value will be one.
Hope you understood by now. Lamda expressions cannot access values with reference of this object. It can only access variables with global reference.
In case 1 if you want to make it work with lamba you have to use obj.count+=1 with name has reference.
And rest of the JavaScript function implementation remains same there is not much difference.

Javascript Properties

Please let me know if question is just dumb and not answerable?
I've just started unit testing with javascript. I have been implementing this blog code into my app. I just confused with name argument being passed to function in javascript. If we talk about Java,Php or any other language they take arguments in construct function and is understandable to use within class something like
$vehicle = new Vehicle('argument here');
Class Vehicle {
protected $name;
function __construct($name) {
$this->name = $name; // we can use the property any where in the class
}
}
//Is name Property? Object? or anything else?
//javascript
(function(name) {
"use strict";
function vehicle(modal) {
this.modal = modal || 'Civic 2015';
}
name.vehicle = vehicle; //? ? ?
})(this);//also why using (this) ?
Also an example would be greatly welcomed.
Javascript doesn't have class (really) and so OOP is handled slightly differently to some of the languages you mention. Often you'll see something like this:
function Vehicle(make, color){
this.make = make;
this.color = color;
}
Vehicle.prototype.getMake = function(){
return this.make;
}
var myCar = new Vehicle('ford', 'green');
myCar.getMake(); //'ford'
As shown in this fiddle I made: https://jsfiddle.net/eqf2apwx/
There are many ways to handle JS objects, however, and I'd suggest you google it a bit, particularly 'Crockford Classless' which is a popular way of handling objects.
The function that you are using above is called self-executing immediate functions, "this" inside such functions always points to the global object, because inside functions that were invoked as functions (that is, not as constructors with new) "this" should always point to the global object.
This pattern is useful because it provides a scope sandbox for your initialization code. Think about the following common scenario: Your code has to perform some setup tasks when the page loads, such as attaching event handlers, creating objects, and so on. All this work needs to be done only once, so there’s no reason to create a reusable named function. But the code also requires some temporary variables, which you won’t
need after the initialization phase is complete. It would be a bad idea to create all those variables as globals. That’s why you need an immediate function—to wrap all your code in its local scope and not leak any variables in the global scope
However, in ECMAScript 5 in strict mode, "this" reference doesn't necessarily point to the global object so you have to adopt a different pattern when your code is in strict mode. Therefore, developers usually pass the reference to "this" from the global scope. SO in your case "this" which is passed as an argument to immediate function is a reference to the global "window" object. Also, this pattern makes the code more interoperable in environments outside the browser because you don't need to hardcode "window" inside the immediate function.

Why pass an entire function definition as an argument instead of just the function name which can be reused?

The former seems to be much more "hip" in JavaScript, and I don't understand why.
Edit: in response to this question possibly being a duplicate, my interest is why, not how. And another question asking only about "closures" in the title wouldn't catch the eye of the person who hasn't made the link between this and closures yet.
tl;dr: Because many functions are actually not reused.
I think you answered your own question:
... instead of just the function name which can be reused?
Many of these are "one-off" cases. The line of code is executed once and the passed function doesn't have to be reused.
For example, if I want to bind an event handler to a body and I don't intend to reuse the event handler anywhere, why should I write
function bodyEventHandler() {}
document.body.addEventListener('click', bodyEventHandler);
and unnecessarily pollute the current scope with bodyEventHandler?
document.body.addEventListener('click', function() {...});
has the same effect, doesn't pollute the scope and keeps the function definition where it is used.
JavaScript is very much event-driven, and most event handlers are actually not going to be reused anywhere else.
Keeping the function definition where the function is used is also a common reason IMO. Some functions are either very simple, but it may not be easy to give them descriptive names.
E.g. if you are not familiar with the term "pluck", would you understand what
var names = users.map(pluck('name'));
really does? Maybe you can infer it from the other variables names.
However,
var names = users.map(function(user) { return user.name; });
makes it immediately clear.
In fact, you will see these even more often, now that ECMAScript 6 introduces arrow functions, which are like lambda functions in other languages:
var names = users.map(user => user.name);
I also think you have a misconception of what exactly happens under the hood when you pass a function:
... pass an entire function definition as an argument instead of just the function name ...
foo(bar) does not pass the name "bar" to foo. It passes the function object that is referenced by the variable bar. That is no different from foo(function() { ... }). The only difference is that we are not (temporarily) storing the function in a variable.

How can function references be executed properly (1)?

win points to window. NS is a temporary namespace for this post. I thought that if I wanted access to setTimeout, I could just copy over the function reference as such:
NS.setTimeout = win.setTimeout;
However, execution will throw an error:
NS_ERROR_XPC_BAD_OP_ON_WN_PROTO: Illegal operation on WrappedNative prototype object # ...
To fix this error, I just did:
NS.setTimeout = function (arg1, arg2) {
return win.setTimeout(arg1, arg2);
};
However, I don't know why this fixed it. I don't know what language mechanics are causing this behavior.
What you want is this :
NS.setTimeout = win.setTimeout.bind(win);
or what you already do, if you want to be compatible with IE8.
Because setTimeout, like many window functions, needs the receiver (this) to be window.
Another IE8 compatible solution, more elegant in my opinion than yours (because it doesn't use the fact you know the number of arguments needed by setTimeout), would be
NS.setTimeout = function(){
return win.setTimeout.apply(win, arguments);
};
The reason why you can't do that is because, when assigining, you're changeing the call context of setTimeout, which isn't allowed.
Nor is it allowed for setInterval, and many of the other native objects/functions. Again: a great rule of thumb: if you don't own the object, don't touch it. Since functions are objects in JS, that rule applies to them, too
check the specs on the global object and its properties/builtin funcitons:
There are certain built-in objects available whenever an ECMAScript program begins execution. One, the global object, is part of the lexical environment of the executing program. Others are accessible as initial properties of the global object.
And so on. But the lexical environment is quite significant. By assigning a reference to the function elsewhere, you could well be masking part of the lexical environment, or exposing too much of the global environment (eg mashups).
This fixed the problem b.c. you are changing the calling object back to the original when you call it.
return win.setTimeout(arg1, arg2);
will set the context ( or this ) back to window where it should be. The other answers are similar in the fact that they change the context to the correct value using bind to apply.

Is it good to write javascript functions inside functions and not use 'new' on the main function?

I now know this works:
function outerfunction(arg1, arg2, arg3) {
var others;
//Some code
innerFunction();
function innerFunction() {
//do some stuff
//I have access to the args and vars of the outerFunction also I can limit the scope of vars in the innerFunction..!
}
//Also
$.ajax({
success : secondInnerFunction;
});
function secondInnerFunction() {
// Has all the same benefits!
}
}
outerFunction();
So, I am not doing a 'new' on the outerFunction, but I am using it as an object! How correct is this, semantically?
There doesn't appear to be anything wrong with what you're doing. new is used to construct a new object from a function that is intended as a constructor function. Without new, no object is created; the function just executes and returns the result.
I assume you're confused about the closure, and how the functions and other variables belonging to the function scope are kept alive after the function exits. If that's the case, I suggest you take a look at the jibbering JavaScript FAQ.
You are not using the outer function as an object. You are using it to provide a closure. The border line is, admittedly, thin, but in this case, you are far away from objects, since you do not pass around any kind of handle to some more generic code invoking methods, all you do is limiting the scope of some variables to the code that needs to be able to see them.
JFTR, there is really no need to give the outer function a name. Just invoke it:
(function() { // just for variable scoping
var others;
...
})()
I do this sort of thing all the time. Yes - javascript blurs the boundary between objects and functions somewhat. Or perhaps, more correctly, a javascript function is just an object that is callable. You would only really use the 'new' prefix if you wanted to have multiple instances of the function. My only suggestion here is that its usually considered good practice to call a function after you've declared it (you are calling the innerFunction before it has been declared) - although that could be considered nit-picking.
This is a valid example.
Functions in JavaScript are first order objects. They can be passed as an argument, returned from a function or even set to a variable. Therefore they are called 'lambda'.
So when you are directly using this function (without new keyword) you are directly dealing with the function as an object. When u are using new keyword, you are dealing with an object instance of the function.

Categories

Resources