I've got an object in JS in which I'm trying to test out the Reactive Framework In an event subscription I'd like to call an instance method of the enclosing class where the subscription is defined, like this;
function MyClass()
{
var DoSomething = function(a,b) { ... }
var InstanceVariable = 1;
this.uiEvent = uiDiv.jqueryUiWidget("widget")
.toObservable("change")
.Subscribe(
function (event)
{
// Want to call the instance method in the enclosing class
DoSomething(1,2);
});
this.uiEvent2 = uiDiv.jqueryUiWidget("widget")
.toObservable("change")
.Subscribe(
function (event)
{
// Want to use the instance variable within here
alert(InstanceVariable);
});
}
How can I do this (since the "this" scope is that of the subscription)? Do I have to pass the function/variable through when setting up the subscription in some way?
If I attempt to do this, I get an error in all browsers saying that the instance variables or methods don't exist: "this" within the scope of the function where I want to call the instance members refers to the Observer and so has functions of OnNext, OnCompleted etc.
Many Thanks,
Paul
Seems to me like your code should work. If you are having any problems I suggest you describe them. However, if you are asking how it works, then you should know about closures. From Wikipedia:
In computer science, a closure is a first-class function with free variables that are bound in the lexical environment. Such a function is said to be "closed over" its free variables. A closure is defined within the scope of its free variables, and the extent of those variables is at least as long as the lifetime of the closure itself. The explicit use of closures is associated with functional programming and with languages such as ML and Lisp. Closures are used to implement continuation passing style, and in this manner, hide state. Constructs such as objects and control structures can thus be implemented with closures.
This means that DoSomething and InstanceVariable are accessible from any method that is defined within the scope where they are defined. There will be a new "instance" of these variables each time the MyClass constructor is called.
Related
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.
I would like to know if defining a function within a function is a good practice in JavaScript.
Here is an example:
module.exports = function() {
function foo() {
// do something
}
...
foo()
...
}
To me, this looks very strange. But I see this often when reading open source projects.
Is it better to define foo outside of the scope of module.exports in the above example? Why and why not?
In Javascript a function can be defined at the global scope or in any function scope. As a general good design practice, you want to limit the scope of a function to only that scope that needs to call it. That means that often you define locally used functions within other functions.
In addition, function declarations declared within another function scope can also access all the other variables within that scope which can be extremely useful.
This serves a number of general benefits:
It keeps the function private to only the scope that needs to use it (it cannot be called from outside the scope in which it is defined unless a reference is explicitly passed to some other function or variable outside the scope).
It keeps you from polluting a top level scope with zillions of named functions, some of which might even have conflicting names in a very large project. In node modules, this is not so much the case because a node module is already a limited scope.
It allows a function to have access to the other variables within that scope.
That was the "general" discussion. Now, within a node module, the code in the module is already within a private scope so it is not as important to declare a function within the exports function as you've done, but I generally follow a practice of declaring a function only in the scope in which it will be used.
In addition, many functions can be declared inline and anonymously and don't even need a name.
In your specific example:
module.exports = function() {
var cntr = 0;
function foo() {
// do something
}
...
foo()
...
}
It really depends upon what you're using foo for. If you are never using it in any other scope, then I would favor declaring it within that scope as you've done.
If you need or want to access other variables within that scope such as the cntr variable I've shown, then it must be declared within the scope.
This is just a technical question about javascript. In javascript, one member of my group found something odd with javascript object creation. For some reason, the parameters in the object are already treated as members without assigning them to any member variables created in the constructor of the object. The parameters are mutable also as seen in the code block below.
Here's the code to show the testing we have being doing.
function NamedItem(name)
{
name = 5;
this.getName = function ()
{
return name;
}
}
document.write(namedItem.getName() + "\n"); //5
Is this legitimate? Is it dangerous?
That's called a closure.
Nested functions can access variables from their parent function and extend the variables' lifetimes beyond the execution of the parent function.
It has nothing to do with objects.
Just to be clear there are some potentially silly things about what you're doing. Let me explain a few principles.
If you declare a variable or variables as arguments to a function such as function(arg1, arg2), in terms of the variables themselves (and not their values) it is essentially the same as saying at the top of your function var arg1; var arg2;. The are declared for you automatically. Even if you try and redeclare them, they'll still work with the passed in arguments!
Functions are objects. Objects can have properties. Therefore functions can have properties, such as this.getName = function().
Like the #SLaks pointed out you're creating a closure in your version of the getName method. A closure captures the state of things above it when it's created. Therefore if there is a name variable in its scope when it's created, it will have access to that name variable in it's scope. It's a very normal practice in JavaScript and you've managed to create a private property (name) with a public accessor function (getName). Well done.
I assume you're using creating instances of NamedItem with the new keyword like this. var item = new NamedItem("javascripter"). Another way (and one that uses less memory than what you are doing is to add the getName() function to the prototype for NamedItem like I show below. The drawback to the prototype approach is that you could just as easily access _name directly. There are no private properties in the traditional sense in JavaScript, but some people use the underscore prefix to indicate to people that they're private and not to use them. This approach (prototypes) use less memory than your approach because if you create multiple instances of NamedItem they all share a single prototype.
Using the prototypes instead:
function NamedItem(name) {
this._name = name
}
NamedItem.prototype.getName = function() {
return this._name
}
Hope that gives you some things to think about!
J
Whats the main purpose of Closures in JS. Is it just used for public and private variables? or is there something else that I missed. I am trying to understand closure and really want to know what are the main advantages of using it.
Closures have to do with how javascript is scoped. To say it another way, because of the scoping choices (i.e. lexical scoping) the javascript designers made, closures are possible.
The advantage of closures in javascript is that it allows you to bind a variable to an execution context.
var closedIn = {};
var f = function(){
closedIn.blah = 'blah'; // closedIn was just "closed in" because I used in the function, but it was defined outside the function.
}
in that example, you have a normal object literal called closedIn. It is accessed in a function. Because of that, javascript knows it has to bring closedIn everywhere it brings the function f, so it is available to f.
The this keyword is tricky. this is always a reference to the execution scope. You can capture the this of one context to use in another context as follows:
var that = this;
var f = function(){
that.somethingOnThat();
// `this` means the scope f, `that` means whatever 'this' was when defined outside of the function
}
This trick can be very useful somethings, if you are coding object oriented javascript and want a callback to have access to some external scope.
To quote from a Javascript book:
"Functions in JavaScript are lexically
rather than dynamically scoped. This
means that they run in the scope in
which they are defined, not the scopee
from which they are executed. When a
function is defined, the current scope
chain is saved and becomes part of the
internal state of the function."
So the clear advantage is that you can bring any object (functions, objects, etc) along with the scope chain as far as is necessary. This is can also be considered a risk, because your apps can easily consume lots of memory if you are not careful.
I think the best phrase to sum up the purpose of closures would be:
Data Encapsulation
With a function closure you can store data in a separate scope, and share it only where necessary.
If you wanted to emulate private static variables, you could define a class inside a function, and define the private static vars within the closure:
(function () {
var foo;
foo = 0;
function MyClass() {
foo += 1;
}
MyClass.prototype = {
howMany: function () {
return foo;
}
};
window.MyClass = MyClass;
}());
Closures are necessary in javascript due to the fact that most API's that require callback functions (for instance, an "onclick" function) do not provide other mechanisms to send parameters to those callback functions (or to explicitly set the "this" pointer). Instead, you need to use closures to allow the callback to access variables in the "parent" function.
I personally wish that they weren't necessary, since they can be hard to understand, make for hard to read code (it's not always clear what exactly is in scope), and make for weird bugs. Instead I wish there was a standard for callbacks that allowed you to send parameters, etc. But I accept that I am in the minority in this view.
As we know, the variables that are defined in functions, have local scope. We can't access them from outside of the function.
Problem 1:
local variables are created when the function is called and they will be destroyed when the function's task is finished. It means local variables have shorter life time than global variables. We may use global variables to overcome that issue.
Global variables are available when the program starts and are destroyed when it ends. They are also available throughout the program.
Problem 2:
Since global variables are accessible throughout the program, they are prone to change from everywhere.
What do we want?
We want to have data persistency + data encapsulation.
We can achieve them by using Closures. By using a closure we can have private variables that are available even after a function's task is finished.
Example:
function initCounter() {
let counter = 0;
return function () {
return ++counter;
}
}
// Each counter is persistent
const countJumps = initCounter();
countJumps();
countJumps();
alert("Jumps count is: " + countJumps());
const countClicks = initCounter();
countClicks();
countClicks();
countClicks();
countClicks();
alert("Clicks count is: " + countClicks());
// Each counter is isolated
alert(counter); // Error: counter is not defined
A local function in the closure declares a variable with the same name which exists in the closure. So, how could we access closure's variable from the local function?
function closure()
{
var xVar;
function func1()
{
var xVar;
// how to distinguish local and closure scopes.
return xVar;
}
return function () { return func1(); };
}
Creating a private object and making private variables as properties of this object could help. But I am wondering if there is a better and neat solution. Can a scope chain help?
I have edited to make it a complete closure. Anyway, closures are not much concern here, it could be considered for inner functions however, there may be a solution with closures somehow.
Thanks
You can't access the scope chain explicitly in JS. Your problem is the age-old one of variable shadowing, but it's that much more maddening because in JS, the scope chain is actually there at runtime, it's just not available for you to access.
You can play some tricks with rejiggering current scope if you use the hated with operator, but that (as well as arguments's caller/callee stuff) really just give you access to objects and functions with their properties. There's no way to say "give me what xVar means in the n-1 runtime scope from right here".
Variables defined in an inner scope hide variable declarations in an outer scope. The "better and neat solution" is not to reuse variable names that way.
In your example the xVar variable is not a closure, because you redefined its scope to each function. To use that variable as a closure continue to declare it with the var command in the closure() function and then do not declare it with the var function in the func1() function. Instead just use the variable immediately in func1().
There is not an easy way to test if a function is a closure or a local variable. You would have to perform some sort of flow control test and then analyze assignments, where assignments occur, and where assignments do not occur. Then you must compare those results. You could write a tool, in JavaScript, to perform that analysis upon a given input and write you a report as output.