最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

jquery - maintain scope with javascript - Stack Overflow

programmeradmin2浏览0评论

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

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
Share Improve this question edited Jul 24, 2010 at 7:09 cynicaljoy asked Jul 24, 2010 at 1:09 cynicaljoycynicaljoy 2,0871 gold badge18 silver badges25 bronze badges 2
  • 2 where do you want to 'maintain scope'? – hvgotcodes Commented Jul 24, 2010 at 1:14
  • this.canvas = undefiend should return [object HTMLCanvasElement] as that is what is set to in the init method. – cynicaljoy Commented Jul 24, 2010 at 1:17
Add a ment  | 

5 Answers 5

Reset to default 4

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

<html>
<head>

    <script type="text/javascript" src="http://ajax.googleapis./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>

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.

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

This will change the scope.

It looks like you're ing 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./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>

Your code has several syntax errors. If handleWindowResize is a method within your Base object, then you should declare it similar to this.init and call it as this.handleWindowResize.

发布评论

评论列表(0)

  1. 暂无评论