Basically, the Stack Trace is a trace of function calls that go on the
Stack. When a program runs, it copies functions from the Heap to the Stack,
in a "Stack" (so to speak) which is a stack of the functions. When a
function is called, a copy of it is put on the Stack to execute. When a
function exits, it is pulled from the Stack. If it calls other functions,
these are stacked on top of it, and each one is pulled off the Stack when it
exits.
The Stack Trace shows the "topmost" (latest) functions called. It helps
identify the chain of execution that led
up to the current situation
(usually an exception). It identifies each function on the Stack in the
order (reversed) in which they appear, with the last one executed at the
top.
Sometimes what you do in your code does not throw an exception until it hits
the .NET Framework components. In these cases, you often have to look down
the stack until you hit your own functions to determine what actually caused
the error.
Category : javascript
Time: 1:32 PM
JavaScript has functional programming characteristics, and that can get in our way until we decide to face and learn it.
Let's first create a simple function that we will be using through the rest of this post. This function will just return an array with the current value of
That
I say it's unfortunate that this is the most common way because it leads us to declare our functions globally by default. And we all know that global members are not exactly the best practice in software programming. This is especially true in JavaScript. Avoid globals in JavaScript, you won't regret it.
The value of this became the object itself. You may be wondering why isn't it still window since that's how the original function had been defined. Well, that's just the way functions are passed around in JavaScript. Function is a standard data type in JavaScript, an object indeed; you can pass them around and copy them. It's as if the entire function with argument list and body was copied and assigned to make in arrayMaker. It's just like defining arrayMaker like this:
This is a major source of bugs in event handling code. Look at these examples.
Clicking the first button will display "btn1" because it's a method invocation and this will be assigned the owner object (the button input element.) Clicking the second button will display "window" because buttonClicked is being called directly (i.e. not like obj.buttonClicked().) This is the same thing that happens when we assign the event handler directly in the element's tag, as we have done for the third button. Clicking the third button does the same of the second button.
That's another advantage of using a library like jQuery. When defining event handlers in jQuery, the library will take care of overriding the value of this and make sure it contains a reference to the element that was the source of the event.
The two methods are similar. The first parameter will override this. They differ on the subsequent arguments. Function.apply() takes an array of values that will be passed as arguments to the function and Function.call() takes the same arguments separately. In practice I believe you'll find that apply() is more convenient in most cases.
Without the new operator your function will just be called like a global function and those properties that we are creating would be created on the global object (window.) Another issue is that, because you typically don't have an explicit return value in your constructor function, you'll end up assigning undefined to some variable if you forget to use new. For these reasons it's a good convention to name your constructor functions starting with an upper case character. This should serve as a reminder to put the new operator before the call.
With that taken care of, the code inside the constructor is very similar to any constructor you probably have written in other languages. The value of this will be the new object that you are trying to initialize.
My thanks to: http://devlicio.us/blogs/sergio_pereira/archive/2009/02/09/javascript-5-ways-to-call-a-function.aspx
JavaScript series: http://devlicio.us/blogs/sergio_pereira/archive/tags/JavaScript-Demystified/default.aspx
Let's first create a simple function that we will be using through the rest of this post. This function will just return an array with the current value of
this
and the two supplied arguments.1) Most common way, unfortunately, global function calls
When we are learning JavaScript we learn how to define functions using the syntax used in the example above. We learn that it's also very easy to call that function — all we need to do is:makeArray('one', 'two'); // => [ window, 'one', 'two' ]
That
makeArray
function isn't just a loose "global" function, it's a method of the global object. Bringing ourselves back to the browser, the global object is mapped to the window
object in this environment. I say it's unfortunate that this is the most common way because it leads us to declare our functions globally by default. And we all know that global members are not exactly the best practice in software programming. This is especially true in JavaScript. Avoid globals in JavaScript, you won't regret it.
JavaScript function invocation rule #1
In a function called directly without an explicit owner object, like
In a function called directly without an explicit owner object, like
myFunction()
, causes the value of this
to be the default object (window
in the browser).2) Method call
Let's now create a small object and use the makeArray function as one of its methods. We will declare the object using the literal notation. Let's also call this method.//creating the object var arrayMaker = { someProperty: 'some value here', make: makeArray }; //invoke the make() method arrayMaker.make('one', 'two'); // => [ arrayMaker, 'one', 'two' ] // alternative syntax, using square brackets arrayMaker['make']('one', 'two'); // => [ arrayMaker, 'one', 'two' ]
The value of this became the object itself. You may be wondering why isn't it still window since that's how the original function had been defined. Well, that's just the way functions are passed around in JavaScript. Function is a standard data type in JavaScript, an object indeed; you can pass them around and copy them. It's as if the entire function with argument list and body was copied and assigned to make in arrayMaker. It's just like defining arrayMaker like this:
var arrayMaker = { someProperty: 'some value here', make: function (arg1, arg2) { return [ this, arg1, arg2 ]; } };
JavaScript function invocation rule #2
In a function called using the method invocation syntax, like
In a function called using the method invocation syntax, like
obj.myFunction()
or obj['myFunction']()
, causes the value of this
to be obj
.This is a major source of bugs in event handling code. Look at these examples.
Clicking the first button will display "btn1" because it's a method invocation and this will be assigned the owner object (the button input element.) Clicking the second button will display "window" because buttonClicked is being called directly (i.e. not like obj.buttonClicked().) This is the same thing that happens when we assign the event handler directly in the element's tag, as we have done for the third button. Clicking the third button does the same of the second button.
That's another advantage of using a library like jQuery. When defining event handlers in jQuery, the library will take care of overriding the value of this and make sure it contains a reference to the element that was the source of the event.
//using jQuery $('#btn1').click( function() { alert( this.id ); // jQuery ensures 'this' will be the button });
3) + 4) Two more: apply() and call()
The more you leverage functions in JavaScript, the more you find yourself passing functions around and needing to invoke them in different contexts. Just like jQuery does in the event handler functions, you'll often need to override the value of this. Remember I told you functions are objects in JavaScript? Functions have predefined methods, two of them are apply() and call(). We can use them to do precisely that kind of overriding.var gasGuzzler = { year: 2008, model: 'Dodge Bailout' }; makeArray.apply( gasGuzzler, [ 'one', 'two' ] ); // => [ gasGuzzler, 'one' , 'two' ] makeArray.call( gasGuzzler, 'one', 'two' ); // => [ gasGuzzler, 'one' , 'two' ]
The two methods are similar. The first parameter will override this. They differ on the subsequent arguments. Function.apply() takes an array of values that will be passed as arguments to the function and Function.call() takes the same arguments separately. In practice I believe you'll find that apply() is more convenient in most cases.
JavaScript function invocation rule #3
If we want to override the value of
If we want to override the value of
this
without copying the function to another object, we can use myFunction.apply( obj )
or myFunction.call( obj )
.5) Constructors
We should be aware that there aren't classes in JavaScript and that any custom type needs a constructor function. It's also a good idea to define the methods of your type using the prototype object, which is a property of the constructor function. Let's create a small type ArrayMaker.//declaring the constructor function ArrayMaker(arg1, arg2) { this.someProperty = 'whatever'; this.theArray = [ this, arg1, arg2 ]; } // declaring instance methods ArrayMaker.prototype = { someMethod: function () { alert( 'someMethod called'); }, getArray: function () { return this.theArray; } }; var am = new ArrayMaker( 'one', 'two' ); var other = new ArrayMaker( 'first', 'second' ); am.getArray(); // => [ am, 'one' , 'two' ]
Without the new operator your function will just be called like a global function and those properties that we are creating would be created on the global object (window.) Another issue is that, because you typically don't have an explicit return value in your constructor function, you'll end up assigning undefined to some variable if you forget to use new. For these reasons it's a good convention to name your constructor functions starting with an upper case character. This should serve as a reminder to put the new operator before the call.
With that taken care of, the code inside the constructor is very similar to any constructor you probably have written in other languages. The value of this will be the new object that you are trying to initialize.
JavaScript function invocation rule #4
When used as a constructor, like
When used as a constructor, like
new MyFunction()
, the value of this
will be a brand new object provided by the JavaScript runtime. If we don't explictly return anything from that function, this
will be considered its return value.It's a wrap
I hope understanding the differences between the invocation styles will help you keep bugs out of your JavaScript code. Some of these bugs can be very tricky to identify and making sure you always know what the value of this will be is a good start to avoiding them in the first place.My thanks to: http://devlicio.us/blogs/sergio_pereira/archive/2009/02/09/javascript-5-ways-to-call-a-function.aspx
JavaScript series: http://devlicio.us/blogs/sergio_pereira/archive/tags/JavaScript-Demystified/default.aspx
Property is a function call. Field is not a call - just access into a memory of the class.
Properties are more maintainable than fields. Some properties do not have the equivalent field - you need to write some code to set/get them.
Simple example: say you have a car object. It has a mileage and a gallons as fields. You can make a property MPG by dividing these fields. Notice that there is no MPG field inside an object - you do it on the fly by using a property. And that property is read-only - you cannot set it. It can only be changed by changing mileage field or gallons field.
From the other hand - the critical code path (large loops, for example) should avoid using a lot of properties or get the properties once before the loop.
Take a look here:
http://msdn.microsoft.com/en-us/library/w86s7x04(VS.80).aspx
Properties are more maintainable than fields. Some properties do not have the equivalent field - you need to write some code to set/get them.
Simple example: say you have a car object. It has a mileage and a gallons as fields. You can make a property MPG by dividing these fields. Notice that there is no MPG field inside an object - you do it on the fly by using a property. And that property is read-only - you cannot set it. It can only be changed by changing mileage field or gallons field.
From the other hand - the critical code path (large loops, for example) should avoid using a lot of properties or get the properties once before the loop.
Take a look here:
http://msdn.microsoft.com/en-us/library/w86s7x04(VS.80).aspx
Subscribe to:
Posts (Atom)