Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

maintain scope with javascript

How do I maintain scope with this?

Original

var Base = new function() {

    var canvas;
    var context;

    this.init = function()
    {
        console.log("Canvas: " + $("canvas")[0])

        this.canvas = $("canvas")[0];
        console.log("Context: " + this.canvas.getContext('2d'))
        this.context = this.canvas.getContext('2d');

        $(window).resize(handleWindowResize);

        handleWindowResize();
    };

    function handleWindowResize()
    {
        console.log("Resize Canvas [" + this.canvas + "] to {width: " +
            $(window).width() + "," + $(window).width() + "}");
        this.canvas.width = $(window).width();
        this.canvas.height = $(window).height(); 
    }
}

$(window).load(function() { new Base.init() });

Ouput:

Canvas: [object HTMLCanvasElement]
Context: [object CanvasRenderingContext2D]
Resize Canvas [undefined] to {width: 1680,1680}
Resize Canvas [undefined] to {width: 1680,1680}

Revised

var Base = function() {
  this.canvas;
  this.context;
}
Base.prototype = {
  init: function()
  {
    console.log("init :: " + this);

    this.canvas = $('canvas')[0];
    this.context = this.canvas.getContext('2d')

    $(window).resize(this.handleWindowResize);
    this.handleWindowResize(null);
  },

  handleWindowResize: function()
  {
    console.log($(window) + " resized set canvas (" + this.canvas + ")" +
        " width,height = " + $(window).width() + "," + $(window).height());
  },

  toString: function()
  {
    return "[Base]";
  }
}

$(window).load(function() { var c = new Base(); c.init(); });

Output: (init)

init :: [Base]
[object Object] resized set canvas ([object HTMLCanvasElement]) width,height = 1659,630

Output: (on window resize)

[object Object] resized set canvas (undefined) width,height = 1658,630
like image 256
cynicaljoy Avatar asked Jul 24 '10 01:07

cynicaljoy


People also ask

What is the scope of JavaScript functions?

JavaScript has function scope: Each function creates a new scope. Scope determines the accessibility (visibility) of these variables. Variables defined inside a function are not accessible (visible) from outside the function.

What is global scope in JavaScript?

Global scope. JavaScript has function scope: Each function creates a new scope. Scope determines the accessibility (visibility) of these variables. Variables defined inside a function are not accessible (visible) from outside the function.

How do you find the scope of a variable in JavaScript?

Every scope has a link to the parent scope. When a variable is used, JavaScript looks down the scope chain until it either finds the requested variable or until it reaches the global scope, which is the end of the scope chain. The autorun3 () inner function has access to the local x3 variable.

What is scope in programming?

The idea of "scope" is that it's where certain functions or variables are accessible from in our code, & the context in which they exist & are executed in. If you've ever seen someone do something like: And wondered what the var _this=this; is all about, hopefully this article should clear it all up. The first scope is Global Scope.


4 Answers

Here's an example of the Module pattern at work:

<html>
<head>

    <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
    <script type="text/javascript">

        var Base = function() {

            //Private Variables
            var canvas;
            var context;

            //Private Function
            function handleWindowResize()
            {
                console.log("Resize Canvas [" + canvas + "] to {width: " + $(window).width() + "," + $(window).width() + "}");
                canvas.width = $(window).width();
                canvas.height = $(window).height(); 
            }

            //Public Functions
            return {

                init: function()
                {
                    console.log("Canvas: " + $("canvas")[0])

                    canvas = $("canvas")[0];
                    console.log("Context: " + canvas.getContext('2d'))
                    context = canvas.getContext('2d');

                    $(window).resize(handleWindowResize);

                    handleWindowResize();
                }

            };

        }();

        $(window).load(function() { Base.init() });

    </script>

</head>
<body>

    <canvas></canvas>

</body>
</html>
like image 190
attack Avatar answered Oct 14 '22 14:10

attack


jQuery changes what object "this" refers to in its callback method. What you should do is store a reference of your objects "this" reference at the beginning:

var Base = new function() {
var self = this;
var canvas;
var context;

And then where you want to refer to the base object use self.

like image 25
Matthew Manela Avatar answered Oct 14 '22 14:10

Matthew Manela


Use: handleWindowResize.call(this) Instead Of: handleWindowResize()

This will change the scope.

like image 42
Maz Avatar answered Oct 14 '22 13:10

Maz


It looks like you're coming from another language and need to get a solid idea of how constructors work in JS.

You have this.name=function(){} for one function, and a function declaration for another. Is there a reason you're using new function for the Base object? Executing new Base.init() doesn't seem quite right, either. The constructor is creating a new object, but you're discarding it, and only using the constructor to execute imperative code? You're not executing Base, so it could just be an object literal.

I really suggest checking out Doug Crockford's articles on inheritance and objects in JS. This SO Question talks about some other object creation techniques. Try searching for Crockford's The Good Parts. What is happening in Crockford's object creation technique?

I discarded the canvas stuff since I haven't worked with canvas. This will execute without errors.

<html><head>
  <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script> 
  <script>
   var Base = {
      canvas:null,
      context:null,

      init:function()
         {
         console.log("Canvas: " + $("#canvas")[0]);

         this.canvas = $("#canvas")[0];
         console.log("Context: " + this.canvas)
         //this.context = this.canvas.getContext('2d');
         this.handleWindowResize=function(){
         console.log("Resize Canvas [" + this.canvas + "] to {width: " + $(window).width() + "," +     $(window).width() + "}");
         this.canvas.style.width = $(window).width();
         this.canvas.style.height = $(window).height();
         }
        } 
      };


      $(window).load(function() { var c= new Base.init(); c.handleWindowResize()});
    </script>
  </head>

  <body>
    <div id='canvas' style='width:400px;background-color:red;height:30px;'>a div called Canvas</div>
  </body>
</html>
like image 22
Cole Avatar answered Oct 14 '22 13:10

Cole