Javascript : Block Scoped Variables & Functions

This article highlights new feature introduced in ECMAScript 6 called “Block Scoped Variable” & “Block Scoped Functions“. In internet, you may find many articles on block scoped variable and functions. But this is an attempt to present the topic in as much simplest and easiest way as I can so that developers of each level can understand the concept clearly.

Hope everyone reading this article knows about the concept of Block Scope. In general, SCOPE refers to the range to which the particular object is relevant and BLOCK SCOPE refers to the range inside the block. So lets dive into this concept quickly without wasting much time.

Block Scoped Variables

As per ECMAScript 6 standard, a new keyword introduced named as LET. Its somehow similar to the keyword VAR, though it has some differences.

Both VAR & LET keyword are same in context of declaring variable but different regarding to its scope. LET is scoped to the nearest enclosing block whereas VAR is scoped to the nearest function block. If both the keyword present outside the block, then it behaves similarly as global.

Example 1 (with VAR keyword) :-

<script>
    for (var i = 0; i < 10; i++) {
        // do something
    }

    document.write(i);
</script>

// Output : 10

Example 1 (with LET keyword) :-

<script>
    for (let i = 0; i < 10; i++) {
        // do something
    }

    document.write(i);
</script>

// Output : ReferenceError: i is not defined

For the above example, with LET keyword, the variable i is locally blocked to the for loop, but in case of VAR keyword, the variable i is global.

Example 2 (with VAR keyword) :-

<html>
    <head>
        <title>Testing Block Scoped Variables</title>
        <style>
            div {
                width: 100px;
                height: 100px;
                background-color: #ccc;
                border: 1px solid #000;
                display: inline-block;
                font-size: 30px;
                text-align: center;
                cursor: pointer;
            }
        </style>
        <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
        <script>
            $(document).ready(function() {
                for(var i = 1; i < 4; i++) {
                    $("#dv_blockScope" + i).on('click', function () {
                        alert(i);
                    });
                }
            });
        </script>
    </head>

    <body>
        <div id="dv_blockScope1">1</div>
        <div id="dv_blockScope2">2</div>
        <div id="dv_blockScope3">3</div>
    </body>
</html>

// This will output 4 on each click as it refers to the same object.

In order to fix the above issue, we need to wrap the click event in an anonymous function and pass i as argument. But without creating function, we can fix the above issue by just using LET instead of VAR as shown in code below.

Example 2 (with LET keyword) :-

<html>
    <head>
        <title>Testing Block Scoped Variables</title>
        <style>
            div {
                width: 100px;
                height: 100px;
                background-color: #ccc;
                border: 1px solid #000;
                display: inline-block;
                font-size: 30px;
                text-align: center;
                cursor: pointer;
            }
        </style>
        <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
        <script>
            $(document).ready(function() {
                for(let i = 1; i < 4; i++) {
                    $("#dv_blockScope" + i).on('click', function () {
                        alert(i);
                    });
                }
            });
        </script>
    </head>
    <body>
        <div id="dv_blockScope1">1</div>
        <div id="dv_blockScope2">2</div>
        <div id="dv_blockScope3">3</div>
    </body>
</html>

// This will output the respective number i.e. 1, 2 & 3.

Block Scoped Functions

According to ECMAScript 6, the syntax for block scoped functions got changed. The function scope can be written in a different and easy manner. Lets go through one example to differentiate.

Example 3 (syntax with ES5) :-

<script>
    (function() {
        // first function
        var operation = function (a, b) {
            return a + b + '<br>';
        }

        document.write(operation(1, 2));  // O/P - 3 (executes 1st function)

        (function () {
            // second function
            var operation = function(a, b) {
                return a * b + '<br>';
            }
    
            document.write(operation(2, 3));  // O/P - 6 (executes 2nd function)
        })();

        document.write(operation(2, 3));  // O/P - 5 (executes 1st function, as it belongs to the main block)
    })();
</script>

The above example contains same method but in different function block. There are some specific notations I used in the above example which let me note it down.
1. While declaring a self executable function, we had to use (function() { .. })();.
2. We had to use var = function (param1, param2, …) { … }; notation to define a function.

But with ECMAScript 6, lets see how the scoped definition for function changed.

Example 3 (syntax with ES6) :-

<script>
    {
        // first function
        function operation(a, b) {
            return a + b + '<br>';
        }

        document.write(operation(1, 2));  // O/P - 3 (executes 1st function)

        {
            // second function
            function operation(a, b) {
                return a * b + '<br>';
            }

            document.write(operation(2, 3));  // O/P - 6 (executes 2nd function)
        }

        document.write(operation(2, 3));  // O/P - 5 (executes 1st function, as it belongs to the main block)
    };
</script>

Check the syntax with ES6.
1. We no need to write a complicated line like this (function() { .. })();. We only have to write { .. };, plain & simple.
2. We no need to use var = function (param1, param2, …) { … };, instead we can directly write function (param1, param2, …) { … }.

Example 4 (syntax with ES5) :-

<script>
    (function foo() {
        let x = 1;

        (function foo() {

            let x = 2;
            document.write(x + '<br>');  // O/P - 2

        })();

        document.write(x + '<br>');  // O/P - 1
    })();
</script>

Example 4 (syntax with ES6) :-

<script>
    {
        let x = 1;

        {
            let x = 2;
            document.write(x + ' <br>'); // 2
        }

        document.write(x + ' <br>'); // 1
    }
</script>

That’s it !!! Hope I am clear on Block Scoped Variables & Block Scoped Functions. Do you find it useful? If yes, then please like and add comments :). Thank you and I will be happy to hear from you 🙂 🙂 .

Note :- Check here for Browser support details.

Advertisements

Beginners guide on jQuery Selectors

In our previous blog, we went through almost all the major CSS selectors and I felt that was helpful for some and helpful for me as well. That’s why I came up with the same kind of way of selecting element using jQuery :).

As we know, jQuery is a light weight javascript library used to manipulate the DOM easily, for CSS manipulation, for effects and animations etc. So, in this blog, we will go through manipulating DOM using selector.

ID Selector :- Selects one element that has a given id attribute. Below example will apply black border to the element which id equals to ‘idMyTest’.

$("#idMyTest").css("border", "1px solid black");

 

Class Selector :- Selects one or more element that has the given class attribute. The below will apply black background to all the elements where the class defines as ‘class-my-test’ in the html document.

$(".class-my-test").css("border", "1px solid black");

 

Type Selector :- Selects every element that has the given type node. Type node can be ‘span’, ‘p'(paragraph), ‘div’, ‘a'(hyperlink), ‘img’ etc.. The example will add border to all the span present in the web document.

$("span").css("border", "1px solid black");

 

Descendant Combination Selector :- Selects all the elements with the type. For below example, it will select all elements inside elements. The below will apply the border to the hyperlink present inside or as child of span element.

$("span a").css("border", "1px solid black");

 

Link History Pseudo-Class Selector :- Selects all unvisited link only. The below will make all the link elements color as blue.

$("a:link").css("color", "blue");

 

User Action Pseudo-Class Selector :- Selects all matched elements which are activated by any user. The below example will make the color as green for the active buttons.

$("a:active").css("color", "green");

 

Universal Selector :- Selects every element of any type, that means apply style to all the attribute of the web page. Below will add green color to all the elements present in DOM.

$("*").css("color", "green");

 

User action pseudo-class Selectors :- Apply the styles on hover or on focus of any element. The below code will make the color red on hover of any link.

$("a:hover").css("color", "red");

 

Lang pseudo-class Selector :- Selects all the elements mentioned in the document language. The language value can be any 2-digit international language (en, fr, nl, de, etc..). The below will apply red color to the text which will be in english language.

$("div:lang(en-us)").css("color", "red");

 

Attribute Selector :- Selects matching string in the value attribute. The below example select all elements which have a title attribute and add a black border.

$("[title]").css("border", "1px solid black");

 

Structural pseudo-class Selector :- Selects the first-child of the given attribute. The below will select the first child (can be a span or div or p element) of span and apply black border to it.

$("div span:first-child").css("border", "1px solid black");

 

Child combination Selector :- Select the direct child elements of the mentioned parent/first selector. The below example will add border to the first span present inside the div.

$("div > span").css("border", "1px double black");

 

Adjacent sibling combination Selector :- Select an element immediately preceded by another element. For the below example, border will apply to <p> elements, placed immediately after <div> elements.

$("div + p").css("border", "1px double black");

 

Negation pseudo-class Selector :- Selects every element that is not of the given element type. The below example applies border to all the element present inside the div, except <p> element.

$("div:not(p)").css("border", "1px double black");

 

Target pseudo-class Selector :- Selects the element being the target of the referring URI. The below will add border to the ‘heading4′ text on click of ‘First’ link.

$("h4:target").css("border", "1px double black");

 

Enabled and Disabled pseudo-class Selector :- Select every enabled/disabled element. The below example will add green border to the enabled input element and gray border to the disabled input element.

$("input:enabled").css("border", "1px solid green");

$("input:disabled").css("border", "1px solid gray");

 

Selected-option pseudo-class Selector :- Select every checked input element i.e. will apply the style to the radio or select element. The below will make the option as red color on checked.

$("input:checked").css("color", "red");

 

Structural pseudo-class Selector :- It select the root element of the document or the web page. The example will make the background color as red for the root element in the hierarchy.

$(":root").css("background-color", "red");

 

Attribute Selector :- Selects every element whose attribute value begins with given string. The below will select every <a> element and make the color red, where href attribute value starts with “https”.

$("a[href^='https']").css("color", "red");

 

General sibling combinator Selector :- Selects the second element only if it is preceded by the first, and both share a common parent. The below will make red color to ‘Second Span’ text.

$("p ~ span").css("color", "red");

<span>First Span</span>
<p>Paragraph</p>
<div>Code Example</div>
<span>Second Span</span>

 

Negation pseudo-class Selector :- Same as CSS3 i.e. it selects every element that is not of the given element type. The only difference is in CSS3, it takes only a single selector list, where in CSS4, it takes multiple. The below will add the border to all html elements except the link.

$(":not(:link), :not(:visited)").css("border", "1px solid black");

 

Matches-any pseudo-class Selector :- Match with every element, provided in the attribute list. The below example will add border to the navigation, article, section and aside of the web page.

$("*:matches(nav, article, section, aside)").css("border", "1px solid black");

 

Local link pseudo-class Selector :- Matches links that point to the domain, where the current page stands for.

$("a[href^=#]").css("border", "1px solid black");

 

Default option pseudo-class Selector :- Selects the default element among others. The below will apply green as background color to the default button among all the buttons.

$(":default").css("background-color", "green");

 

Validity pseudo-class Selector :- Match the elements which has its value attribute come inside/outside the specified range. It is divided into 2 selectors i.e. :in-range and :out-of-range.

$("input:in-range").css("background-color", "green");

$("input:out-of-range").css("background-color", "red");

 

Optionality pseudo-class Selector :- Select every form element which are optional or required.

$("input:required").css("background-color", "red");

$("input:optional").css("background-color", "grey");

 

Mutability pseudo-class Selector :- Selects all the elements of the page, where the contents are writable or not.

$("input:read-only").css("background-color", "gray");

$("input:read-write").css("background-color", "green");

 

Miscellaneous :-

1. Animated Selector :- Select all elements that are undergoing animation.

$("img:animated").toggleClass("animated");

 

2. Attribute contains prefix Selector :- Selects element that starts with the specified attribute. The attribute value should either equal to or should start with that string followed by a hyphen (-). The below will apply outline to the first and third link, not to the second and fourth link.

<a title="test">First link</a>
<a title="this is a test">will not be outlined - second</a>
<a title="test-account">third link</a>
<a title="testing">will not be outlined - fourth</a>

$("a[title|='test']").css("border", "1px solid black");

 

3. Attribute contains Selector :- Selects all the elements that have the specified attribute in any part of the string. The below will apply outline to all except the second link.

<a title="test">First link</a>
<a title="account-check">will not be outlined - second</a>
<a title="test-account">third link</a>
<a title="testing">fourth link</a>

$("a[title*='test']").css("border", "1px solid black");

 

4. Attribute contains word Selector :- Selects the specified element which contains the specific word, delimited by a space. The below will apply the outline to the first link only.

<a title="test">First link</a>
<a title="account-check">will not be outlined - second</a>
<a title="test-account">will not be outlined - third</a>
<a title="testing">will not be outlined - fourth</a>

$("a[title~='test']").css("border", "1px solid black");

 

5. Attribute ends with Selector :- Selects all elements which have the specified attribute with ending exactly match with a given value. The below will apply the outline to first and fourth link.

<a title="test">First link</a>
<a title="account-check">will not be outlined - second</a>
<a title="test-account">will not be outlined - third</a>
<a title="account-test">fourth link</a>

$("a[title$='test']").css("border", "1px solid black");

 

6. Attribute starts with Selector :- Selects all elements which have the specified attribute with starting exactly match with a given value. The below will apply the outline to first and third link.

<a title="test">First link</a>
<a title="account-check">will not be outlined - second</a>
<a title="test-account">third link</a>
<a title="account-test">will not be outlined - fourth</a>

$("a[title^='test']").css("border", "1px solid black");

 

7. Attribute not equal Selector :- Selects all elements which does not match with the specified attribute in the string. Below will outline the second link.

<a title="test">will not be outlined - First</a>
<a title="account-check">second link</a>
<a title="test-account">third link</a>
<a title="account-test">fourth link</a>

$("a[title!='test']").css("border", "1px solid black");

 

8. :eq() Selector :- Select the x index element within the matched set. The below will apply red color to the 3rd list element.

$("li:eq(3)").css("color", "red");

 

9. :nth-child() Selector :- Selects nth child of the parent. The below will apply red color to the 3rd child of each unordered list.

$("ul li:nth-child(3)").css("color", "red");

 

10. :nth-last-child() Selector :- Selects nth child of the parent, counting from last to first. The below will apply red color to the 3rd child from last of each unordered list.

$("ul li:nth-last-child(3)").css("color", "red");

 

Great!! 🙂 We covered almost all the jQuery selector with small example. But, there can be more also, if we will combine two or more selected. Do you really find it useful? 🙂 If yes, then please like and add some comments, if you want.

Thanks 🙂 and will be happy to listen from you 🙂 :).