Jump to content

understanding JS (this keyword)


niche

Recommended Posts

It sounds like you're still not understanding what scope is. The default scope for code is the window object. If you just call a function like alert, or prompt, since the scope is the window object you're calling the built-in window.alert or window.prompt functions (inside alert, this refers to the window object). When you call document.write, the write method executes in the scope of the document object (inside write, this refers to the document object).Run this example and see what happens, I've created an object with some of the same properties as the window object, so the test function can either be executed in the scope of the window object or the new object:

var some_object = {  location: 'a test location',  prompt: function(str)  {	alert('custom prompt function called.\n' + str);  }};function test(str){  if (this == window)  {	alert('test function called in window scope');  }  else  {	alert('test function NOT called in window scope');  }  alert('Location: ' + this.location);  this.prompt(str);}test('test prompt 1');test.call(window, 'test prompt 2');test.call(some_object, 'test prompt 3');

When that function runs this.prompt, it is running the prompt method in the current scope. Sometimes that scope is the window object, where it runs window.prompt, and sometimes the scope is the custom object, where it runs the custom function. The function.call method lets you choose what scope to execute the function in. The first call to test executes in the default scope, which is the window object, the second call explicitly executes in the scope of the window object, and the third call executes in the scope of the custom object.Hopefully that helps you understand what the scope means.

Link to comment
Share on other sites

The only way I was able to get the script to work was like this, but it put my browser in an endless loop. How did you want me to run it?How I tried to run it:

<html><head><script language="javascript" type="text/javascript"> var some_object = {  location: 'a test location',  prompt: function(str)  {    alert('custom prompt function called.\n' + str);  }};function test(str){  if (this == window)  {    alert('test function called in window scope');  }  else  {    alert('test function NOT called in window scope');  }  alert('Location: ' + this.location);  this.prompt(str);}test('test prompt 1');test.call(window, 'test prompt 2');test.call(some_object, 'test prompt 3');</script></head><body></body></html>

Link to comment
Share on other sites

it's definitely not an endless loop. It's just that for each test function call, you get an alert when it does the if/else check, the there's an alert with the location, and then a prompt. (that's three boxes per test, for a total of nine alerts/prompts) AND, when you call test and you pass some_object to the call method, the scope of some_object contains a custom prompt which has an alert inside it. If you just read the alerts/prompts and look at the code, you should be able to make sense of the order of things.

Link to comment
Share on other sites

I got seven boxes.thescientist is right about having a sense of what's happening, but I don't understand how the notation produces 7 boxes

test('test prompt 1');test.call(window, 'test prompt 2');test.call(some_object, 'test prompt 3');

That's probably part of my problem. How does it work starting with "test('test prompt 1');"? Test is the function, but I don't understand why it's looping (or appearing to loop).

Link to comment
Share on other sites

Look at what the test function does. It shows one of two alert boxes based on the scope, then another alert box to show the location property in the scope, then it calls the prompt function in the scope. Each time the test function gets executed it should result in 3 boxes appearing. The first either says that the function was or was not called in the window scope, then the location, then the prompt. In the last case the location and prompt are custom because the test function was called in the scope of the some_object object. There's no looping involved, just three function calls that each produce three alert or prompt boxes.

Link to comment
Share on other sites

I got seven boxes.thescientist is right about having a sense of what's happening, but I don't understand how the notation produces 7 boxes
test('test prompt 1');test.call(window, 'test prompt 2');test.call(some_object, 'test prompt 3');

That's probably part of my problem. How does it work starting with "test('test prompt 1');"? Test is the function, but I don't understand why it's looping (or appearing to loop).

you are making three calls to test, and using call, he is explicitly defining the scope from which the test is be executed in. and it should be 9 boxes. (3 boxes per test).
Link to comment
Share on other sites

For some reason the prompts weren't displaying in ff or ie. I think it had something to do with using a scripted window.So, I used chrome and got 7 alerts and 2 prompts.Here's what I think I'm seeing:re: test('test prompt 1'); = test.call(window, 'test prompt 2'); I think the point is that the window object is implied in the first example and is explicit in the the second. re: test.call(some_object, 'test prompt 3');demonstrates the some_object function is not in the window scopecorrect?

Link to comment
Share on other sites

The third one demonstrates that the function being executed is not being executed in the window scope, it's being executed in the some_object scope. The some_object variable is in fact defined in the window scope (it could also be referred to as window.some_object, since the window object is the default scope). But yeah, the first two are the same because the window scope is the default, and the third is being called in the scope of some_object instead of window. So in the first two calls of the test function, this refers to the window object. In the third call, this refers to some_object.

Link to comment
Share on other sites

i understand calling a function by: test('test prompt 1'); ,but I don't understand the the notation of: test.call(window, 'test prompt 2'); . Would you explain?

Link to comment
Share on other sites

this refers to the scope of whatever the code is executing is in. in this context, this referes to the input element. it just so happens to be that this.form will refer to the parent form element of the input. be aware it is situation dependent, and this can cause developers problems if they don't understand scope correctly, and as such that's why closures can be such a tricky concept to some people.
i'm not sure what you mean by "closures" here.
Link to comment
Share on other sites

but I don't understand the the notation of: test.call(window, 'test prompt 2');
This is the documentation for the function.call method:https://developer.mozilla.org/en/JavaScript...s/function/callLike it says, you can pass a scope to be used as this inside the function, plus whatever arguments you actually want to pass to the function.Remember that everything in Javascript is an object, even functions are objects. That's why functions can have properties and methods, like the function.call method. This is the documentation for functions, look at the list of properties and methods:https://developer.mozilla.org/en/JavaScript...bjects/FunctionFor example, it says that functions have a length property, which holds the number of arguments the function expects. So you can do this:
function test(arg1, arg2){}alert(test.length);

And you'll see that it alerts the number 2, because the test function takes 2 arguments.

i'm not sure what you mean by "closures" here.
That's a pretty broad topic:http://www.google.com/search?client=opera&...channel=suggest
Link to comment
Share on other sites

i understand calling a function by: test('test prompt 1'); ,but I don't understand the the notation of: test.call(window, 'test prompt 2'); . Would you explain?
by looking up call, then it should make a little more sense, and is more or less what JSG previously explained.
The third one demonstrates that the function being executed is not being executed in the window scope, it's being executed in the some_object scope. The some_object variable is in fact defined in the window scope (it could also be referred to as window.some_object, since the window object is the default scope). But yeah, the first two are the same because the window scope is the default, and the third is being called in the scope of some_object instead of window. So in the first two calls of the test function, this refers to the window object. In the third call, this refers to some_object.
https://developer.mozilla.org/en/JavaScript...s/function/call
i'm not sure what you mean by "closures" here.
https://developer.mozilla.org/en/JavaScript/Guide/Closures
Link to comment
Share on other sites

thescientist is right about the clarity that JSG's call ref produced. Who'd thought there'd be a method of changing the this object of a function (I hope I'm using the term method correctly).With so much cleared-up, I need to ask about "location: 'a test location', prompt: function(str)". What's the ";" saying?

Link to comment
Share on other sites

errr... semi-colons are how you end a statement in Javascript. :)Notice how they are all over the place? They are not necessarily needed, but it is generally good practice to use them.

Link to comment
Share on other sites

If you're asking about the colon, not semicolon, it's how you define an object literal. This:

var some_object = {  location: 'a test location',  prompt: function(str)  {	alert('custom prompt function called.\n' + str);  }};

Is the same as this:

var some_object = new Object();some_object.location = 'a test location';some_object.prompt = function(str){  alert('custom prompt function called.\n' + str);}

Those are two ways to make the same thing happen, creating an object with properties and methods. If you're asking about the semicolon at the end of the object definition, it's not required but I put it there for clarity.

Link to comment
Share on other sites

...If you're asking about the semicolon at the end of a object definition, it's not required but I put it there for clarity.
it is if you have multiple lines, you can't just press "Enter" for a new line at the end of a statement.
Link to comment
Share on other sites

JSG is correct I meant to use a semicolon.Is there a test for the value of the this keyword. Obviously, JSG's script evaluated it, "if (this == window)".

Link to comment
Share on other sites

JSG is correct I meant to use a semicolon.Is there a test for the value of the this keyword. Obviously, JSG's script evaluated it, "if (this == window)".
what do you mean? It will be different in almost every scenario. He was using the test to highlight a point. It's meant to define scope, and that changes a lot during the running of an application. You can log it or alert it if you are interested in seeing the value at a given moment however.
Link to comment
Share on other sites

it is if you have multiple lines, you can't just press "Enter" for a new line at the end of a statement.
In Javascript they're pretty optional, actually. This will run just fine:
var some_object = new Object()some_object.location = 'a test location'some_object.prompt = function(str){  alert('custom prompt function called.\n' + str)}

Is there a test for the value of the this keyword.
It's an object, so you can test it the way you do any other object.
Link to comment
Share on other sites

scope... changes a lot during the running of an application.
I see the point of JSG's script as we can (and probably should) control for scope. Since scope and ownership are linked, why create any doubt about either. Just pass the work to a function and control for scope when needed.That implies, that the use of inline events may not be appropriate. Additional reading has left me with the belief that the script I originally present is subject to the "evil" eval() function.
Link to comment
Share on other sites

This is the longest topic for me so far. I need to thank everyone that helped me with the concept of Scope. I'm sure it's a topic I will refer to again and again. Thanks to Ingolme , Deirdre's Dad, thescientist , ShadowMage, justsomeguy, and edGetItTypee.

Link to comment
Share on other sites

You'll use the concept of scoping in any reasonably complex script. Even something as simple as a stopwatch, since I built it as a "widget" that can be added to other objects, like a "workspace", the couple hundred lines of code to implement the stopwatch contains this over 60 times. So it's definitely something you'll be using for anything other than basic scripting.

Link to comment
Share on other sites

I've already referred back to it a couple of times. Thanks again to everyone's help.

Link to comment
Share on other sites

Archived

This topic is now archived and is closed to further replies.

×
×
  • Create New...