I was trying to understand Function Scope vs Gobal Scope, with the below example:
<script>
// The following variables are defined in the global scope
var num1 = 2,
num2 = 3,
name = "Chamahk";
// This function is defined in the global scope
function multiply() {
return num1 * num2;
}
console.log(multiply()); // Returns 60
// A nested function example
function getScore () {
var num1 = 20,
num2 = 30;
function add() {
var num1 = 200,
num2 = 300;
return name + " scored " + (num1 * num2);
}
return add();
}
console.log(getScore()); // Returns "Chamahk scored 60000"
</script>
I googled and found that Global Scoped variable can be accessed using this. changing the return code to
return name + " scored " + (this.num1 * this.num2);
gave output as "Chamahk scored 6", means this is accessing the global var num1 and num2.
This is clear, but what i wanted to know, how to access the num1 and num2 declared in getScore() function
.i.e. to get the output as 600.
I have to say your question is a little confusing.
Generally you would want to use parameters to your functions, to pass values around.
The reason you are getting 60000, is because in your add function you are setting num1, and num2 to 200 and 300.
If you changed your add function to take num1, and num2 as parameters, and not redeclare them, you could pass in your values in getScore();
e.g return add(num1, num2);
<script>
// The following variables are defined in the global scope
var num1 = 2,
num2 = 3,
name = "Chamahk";
// This function is defined in the global scope
function multiply(num1, num2) {
return num1 * num2;
}
console.log(multiply(num1, num2)); // Returns 6!!!
// A nested function example
function getScore () {
var num1 = 20,
num2 = 30;
function add(num1, num2) {
return name + " scored " + (num1 * num2);
}
return add(num1, num2);
}
console.log(getScore()); // Returns "Chamahk scored 60000"
</script>
Related
I'm learning closures... albeit slowly and I have come across the following example which provides an example of how closures 'close over' the variables/constants within their scope. I'll post the code first and ask my question after:
func countingClosure() -> () -> Int {
var counter = 0
let incrementCounter: () -> Int = {
counter += 1
return counter
}
return incrementCounter
}
let counter1 = countingClosure()
let counter2 = countingClosure()
counter1() // 1
counter2() // 1
counter1() // 2
counter1() // 3
counter2() // 2
I get the function block and can see how it returns the value it does. What is throwing me is how counter1 and counter2 retain their values, or, maybe, how the function retains the value (which I didn't think they could?). Surely every time counter1 or counter2 is called, counter resets to 0 as its declared inside the function?
I know it's right as the code compiles, I just can't understand how the Int value returned by counterClosure function is retained?
If you rename some of your names, perhaps it becomes a bit clearer:
func makeANewAutoIncrementingClosure() -> () -> Int {
// Initialize a variable, lives on stack initially but...
var counter = 0
let incrementingCounterClosure: () -> Int = {
// counter is captured and its storage is
// therefore moved from the stack to
// somewhere that hangs around as long as this function
// does
counter += 1
return counter
}
// Now we return this new closure, which is like
// [ function ]--attached to its closed over vars--> {counter: 0}
return incrementingCounterClosure
}
makeANewAutoIncrementingClosure // () -> () -> Int
// is a function that returns a closure that starts out closing over 0
let incr1 = makeANewAutoIncrementingClosure() // () -> Int
// a function that increments its captured int and returns it
let incr2 = makeANewAutoIncrementingClosure()
incr1() // 1 this does not call makeANewAutoIncrementingClosure, it calls the incr1 function (i.e. the incrementingCounterClosure). No assignments to 0 involved
incr2() // 1
incr1() // 2
incr1() // 3
incr2() // 2
I'm trying to understand better the closures in swift and I've tried to create a silly function with a completion handler that returns a value but this value goes nowhere...
here's what I did..
func productToString(num: Int,num2: Int,completion: (Int)->String){
let result = num * num2
completion(result)
}
let numberToString = productToString(num: 3, num2: 6) { (res) -> String in
return "string:\(res)"
}
print(numberToString) // print statement prints ()
when I tried to save this return value in a variable it returned just a pair of curvy brackets.
how should I use this return value?
You're returning the value into the productToString function but not doing anything else with it.
func productToString(num: Int,num2: Int,completion: (Int)->String){
let result = num * num2
completion(result) // <--- Your return value ends up here
}
If you want to print the result you have to return it again out of the productToString function.
func productToString(num: Int,num2: Int,completion: (Int)->String) -> String {
let result = num * num2
return completion(result)
}
Sidenote: The empty brackets that are printed are an empty tuple which is equivalent to Void in Swift.
I want to select a date in calendar picker using protractor. Below is the snippet of code, that I have written in my script:
if (dat <= 24) {
var us_dat = element(by.xpath("(//a[text()='" + dat + "'])[1]"));
} else {
var us_dat = element(by.xpath("(//a[text()='" + dat + "'])[1]"));
if (us_dat.isEnabled() == false) {
var us_dat = element(by.xpath("(//a[text()='" + dat + "'])[2]"));
}
}
us_dat.click();
browser.sleep(1000);
where dat is a variable, where I have stored the date that needs to be selected in the calendar picker.
During debugging, I found that, when the date is greater than 24, the code is checking the "if" block present under the "else" block. However, it returns a value of undefined and hence it is skipping the action written inside the "if" block. May I know why it is returning a value of "undefined", instead of true or false please?
Please let me know if any further details are required.
Because all Protractor's API is Async and return promise. So isEnabled() is not return Boolean value directly, you can't directly compare it with a boolean value. You should do the comparing in then() or use await.
Another thing, you no need to put xpath into (), like (//a[text()='click me']).
var us_dat = element(by.xpath("//a[text()='" + dat + "'][1]"));
us_dat.isEnabled().then(function(enabled){
if (dat > 24 && enabled=== false) {
return element(by.xpath("//a[text()='" + dat + "'][2]"));
} else {
return us_dat;
}
})
.then(function(ele){
ele.click();
browser.sleep(1000);
});
try to use this method will work
isEnable: function (element) {
return element.isEnabled();
},
The code result is:
num1 is Optional(5)
num2 is Optional(5)
num2 is 5
I want to know why in if{} num2 is an optional value, but print "num2 is 5"
var optionalNum : Int? = 5
let num1 = optionalNum
print("num1 is \(num1)")
if let num2 = optionalNum {
print("num2 is \(optionalNum)")
print("num2 is \(num2)")
} else {
print("optionalNum does not hold a value")
}
When you write
if let num2 = optionalNum { ...
You are performing an optional binding.
In plain english it means
If optionalNum contains a value, then
create a new constant num2 containing that value
AND execute the block inside the { ... }
AND make available the new num2 constant inside the block
So inside the block num2 is NOT an optional. So when you print it you get the plain value. This is the reason why it prints
num2 is 5
For the following code:
inc = -> value = (value ? 0) + 1
dec = -> value = (value ? 0) - 1
print = -> console.log value ? 0
How can you make this work properly, so inc and dec close upon value instead of creating separate function-local variables, in the way other than explicitly assigning something to value?
In plain Javascript, you would just declare var value at outer scope:
var value;
function inc() { value = (value || 0) + 1; };
function dec() { value = (value || 0) - 1; };
function print() { console.log(value || 0); };
What is CoffeeScript way for exactly the same thing?
In CoffeeScript, the way to introduce a local variable is to assign to the variable in the appropriate scope.
This is simply the way that CoffeeScript was defined and as such is similar to Python or Ruby, which do not require a "variable declaration", except CoffeeScript also allows forward access. A side-effect is that one cannot shadow a lexical variable.
Just as with the placement of var in JavaScript, where this assignment is done (as long as it is in the correct scope) does not affect the scope of the variable.
Given
x = undefined
f = -> x
// JS
var f, x;
x = void 0;
f = function() {
return x;
};
Given
f = -> x
x = undefined
// JS
var f, x;
f = function() {
return x;
};
x = void 0;