Tuesday, October 25, 2016

Why can't we use click() as button's event handler function name in JavaScript?

As JavaScript developers, many of us might have encountered situation where we defined a function for handling events such as Button's onclick and the function never gets executed. After long time of googling, when we change the name of function, it just starts working and we move to next step without digging why it didn't work for that function name. This post is a small journey towards the answer of why we can't have click() to handle button.onclick.

Lets start with code to see what is this issue. Below code is a simple HTML file which has 2 buttons with ids btn1 and btn2 respectively. Both the buttons have onclick event handled.

<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="utf-8" />
    <script type="text/javascript">
        function click() {
            alert("click");
        }

        function click_handler() {
            alert(this);
            alert("click_handler");
        }
    </script>
</head>
<body>
    <button id="btn1" onclick="click()">btn1 uses click()</button>
    <button id="btn2" onclick="click_handler()">btn2 uses click_handler()</button>
</body>
</html>

For btn1 click function is used as onclick hander and for btn2 the handler function is click_handler. If we save these contents as html file and run, we could see that the btn2 click is handled properly by calling the click_handler(). But btn1's click() is never invoked. What is happening here?

Quick google may tell us that there is already a click() method defined globally or at document level to call the event handlers and that is the reason why our click() is not working.

But if we use F12 developer tools and check click function on window and document we could see its undefined.

Note:We have to check for system defined click function by removing our click function. Else it will see our click function.

Before going to next steps lets see what will happen if we introduce below line to the above HTML page just above closing of body tag ie above </body>

    <button id="btn3" onclick="window.click()">btn3 uses click()</button>

We can see the btn3 click is invoking the event handler function click(). So there is nothing special about the function name click(). Hence we can conclude that the issue of conflicting names is somewhere else.

Is there any click function on the button element? 

Now lets check if there is any click function defined already in the button element? For that put a break point anywhere in the click_handler() and run with F12 developer tools open.

Click on the btn2 and type the below line in the F12 console window.

   document.getElementById('btn1').click 

We can see the below output which confirms there is a system defined click function on the button object.

function click() { [native code] }

This confirms the reason for name conflict. Below code lists all the functions defined on button element.

for(var p in document.getElementById('btn1'))
    if(typeof document.getElementById('btn1')[p] === "function") 
      console.log(p);

Happy Scripting...

Tuesday, October 18, 2016

Caution JavaScript Ahead - Difference between >> & >>>

Introduction

As we know inside the computer everything is kept as binary 1 or 0. We can shift the bits to left or right using our program for accomplishing various tasks. In JavaScript there is one more feature for right shifting called unsigned shifting that is what we are going to discuss in this post. Below are some prerequisites before we discuss the same.

Bitwise operations happen on 32 bit numbers only

The first thing we need to know about JavaScript bit manipulation is that it works for 32 bit numbers.

Negative numbers are represented as 2's complement

When the negative numbers are stored, they use 2's complement form.

Signed right shifting >>

Here the sign of the number will not be changed due to shifting. The sign bit will make copies and propagate to the right side when the bits are shifted. An example below. 


var binary= (7>>1).toString(); 
console.log(binary);
binary= (-7>>1).toString(); 
console.log(binary);

Output - 
3
-4

How we got 3 is clear as its simple right shift. The -4 came instead of -3 because it uses 2's complement. That details are there in one of my previous post.

Unsigned right shifting >>>

Lets see what will happen in unsigned shifting. The main difference is that the sign bit just won't propagate to the right side without making copy. Hence the sign will change. Since the bits added to the left are 0s the sign of -ve number will change to +ve. 


var binary= (7>>>1).toString(); 
console.log(binary);
binary= (-7>>>1).toString(2); 
console.log(binary);

Output - 
3
2147483644

The negative number became positive. Lets see how that happened.
11111111 11111111 11111111 11111001 - 2's complement of -7
01111111 11111111 11111111 11111100 - After shifting bits one time to right

Look at the left most sign bit it changed to 0 which means its a +ve number now. What is that number? Its 2147483644.

Left shifting <<

The point to remember here is that the unsigned shifting is not there for left shifting operation. The sign bit can be overwritten by the bit right to that and that becomes the new sign of the number.


var binary= (1<<31).toString
console.log(binary);

Output - 
-2147483648

How this -ve number came?
00000000 00000000 00000000 00000001 - 1 in 32 bit rep
10000000 00000000 00000000 00000000 - shifted left 31 times 

The sign bit is negative hence its in 2's complement. Get the number from this 2's complement format. Its -2147483648

References

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Bitwise_Operators
http://stackoverflow.com/questions/14061999/why-does-0x80000000-1-in-javascript-produce-a-negative-value
http://blog.revathskumar.com/2014/03/javascript-shift-operators.html
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/MAX_SAFE_INTEGER

Tuesday, October 11, 2016

What events do which delegates don't

Events v/s Delegates in .Net

If someone is a .Net developer he/she might have heard faced this famous question of what is the difference between events and delegates? Here the differences are summarized and given links to external sites as there are many resources available on the same and don't wanted to create another duplicate.

As everyone knows without delegates where is no event and event is just a multicast delegate. 

Invocation

The main difference is that event cannot be raised/invoked from outside of the class which declare it. If an object exposes a delegate as property or field anybody who has access to that property can invoke that delegate.

Protection

If we expose an delegate as public property, the consumers can overwrite other consumers. But in case of events its not possible. Events just add new subscriber to the existing list of subscribers.

Declaration

 An interface can declare and event and force the implementer to raise notification.This can be done by having a method in interface which accepts and delegate and get that invoked by implementer(s). But declaring event is more readable or easy to use.

Tuesday, October 4, 2016

Finding N HigestRatedRelatedMovies- Amazon interview coding challenge via HackerRank

Below is a coding question from Amazon interview I had attended in the past. It was through HackerRank which I had to complete within 90 mins. There are now many sites like HackerRank which can be used to screen developers prior to the face to face or telephonic. That saves a lot of time for companies. But there are very less companies using these options including my previous company where I pressed hard to get this into interview process.

I am not copy pasting the question and initial code snippet as is from HackerRank as it may bring this page in case they reuse the question.Instead this version has slight modifications such as using property instead of Java like get methods etc...

Question

  • Find highest rated N movies which are related to given movie
  • Movie relation is two way
  • The result list should not contain the Movie which we start with.
  • The highest rated movie can be in any level of relation. 
Basically needs to fill code inside the function below function present in MovieFinder class

getHighestRatedRelatedMovies(Movie root,int numer)

Below is the code snippet. We can have helper methods if required.

public class Movie
{
    public int Id { getprivate set; }
    public double Rating { get;private set; }
    public IList<Movie> RelatedMovies { getprivate set; }
    public Movie(int id,double rating)
    {
        this.Id = id;this.Rating = rating;
        this.RelatedMovies = new List<Movie>();
    }
    public void AddRelatedMovie(Movie movie)
    {
        this.RelatedMovies.Add(movie);
        movie.RelatedMovies.Add(this);
    }
}
public class MovieFinder
{
    public IEnumerable<Movie> getHighestRatedRelatedMovies(Movie root, 
                                                           int numberOfMoviesToSelect)
    {
       //Logic to return appropriate movies
    }
}
class MovieFinderTests
{
    public void Test()
    {
        Movie a = new Movie(1,1.5F);
        Movie b = new Movie(23.5F);
        Movie c = new Movie(32.5F);
        Movie d = new Movie(44.6F);
        a.AddRelatedMovie(b);
        a.AddRelatedMovie(c);
        b.AddRelatedMovie(d);
        c.AddRelatedMovie(d);
 
        Console.WriteLine("getHighestRatedRelatedMovies(a,2) returns Movies 2,4");
        LogMovies(new MovieFinder().getHighestRatedRelatedMovies(a, 2));
        Console.WriteLine("getHighestRatedRelatedMovies(a,1) returns Movie 4");
        LogMovies(new MovieFinder().getHighestRatedRelatedMovies(a, 1));
        Console.WriteLine("getHighestRatedRelatedMovies(a,4) returns Movies 2,3,4");
        LogMovies(new MovieFinder().getHighestRatedRelatedMovies(a, 4));
        Console.WriteLine("getHighestRatedRelatedMovies(c,3) returns Movies 1,2,4");
        LogMovies(new MovieFinder().getHighestRatedRelatedMovies(c, 3));
        Console.WriteLine("getHighestRatedRelatedMovies(b,2) returns Movies 3,4");
        LogMovies(new MovieFinder().getHighestRatedRelatedMovies(b, 2));
    }
 
    private void LogMovies(IEnumerable<Movie> movies)
    {
        foreach(Movie m in movies)
        {
            Console.WriteLine($"Id {m.Id}, Rating {m.Rating}");
        }
    }
}

Thoughts on solution

  • We have to visit all the related nodes anyway.
  • We have to skip visiting previously visited nodes without adding extra flag on Movie class.

Approach 1-Depth first traverse, Sort and take N top movies

One of the method to solve this problem is given below. There are some more ways. May be I can  share later.

public IEnumerable<Movie> getHighestRatedRelatedMovies(Movie root, int numberOfMoviesToSelect)
{
        IList<Movie> movies = new List<Movie>();
        FillList(root, movies);
        movies.Remove(root);
        return movies.OrderByDescending(m => m.Rating).Take(numberOfMoviesToSelect);
} 
private void FillList(Movie node, IList<Movie> movies)
{
        if( movies.Contains(node) == false)
        {
            movies.Add(node);
            foreach(Movie m in node.RelatedMovies)
            {
                FillList(m, movies);
            }
        }
}

This is plain solution which satisfies the requirements. It may not be the high performing memory efficient logic. In next posts, lets see optimized version of this.