2010-07-24 34 views
6

Làm cách nào để duy trì phạm vi với điều này?duy trì phạm vi với javascript

gốc

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: (trên cửa sổ thay đổi kích thước)

[object Object] resized set canvas (undefined) width,height = 1658,630
+2

nơi nào bạn muốn 'duy trì phạm vi'? – hvgotcodes

+0

này.canvas = undefiend phải trả về [object HTMLCanvasElement] vì đó là những gì được đặt trong phương thức init. – cynicaljoy

Trả lời

4

Dưới đây là một ví dụ về Module pattern tại nơi làm việc:

<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> 
+0

cảm ơn điều này thật tuyệt vời – cynicaljoy

3

thay đổi jQuery gì đối tượng "này" đề cập đến trong phương pháp gọi lại nó. Những gì bạn nên làm là lưu trữ tham chiếu về các đối tượng "này" tham chiếu của bạn ở đầu:

Và sau đó bạn muốn tham khảo tự sử dụng đối tượng cơ sở.

+0

Tôi không biết ai đã bỏ phiếu cho đề xuất của bạn, nhưng đây là người duy nhất đã thực sự làm việc cho đến nay. Cảm ơn! – cynicaljoy

0

Mã của bạn có một số lỗi cú pháp. Nếu handleWindowResize là một phương thức trong đối tượng Cơ sở của bạn, thì bạn nên khai báo nó tương tự như this.init và gọi nó là this.handleWindowResize.

+0

Mã không có lỗi cú pháp. Nó có thể có định dạng kém, nhưng trong cả hai trường hợp khi tuyên bố một tuyên bố như vậy, một điều _helpful_ hơn là chỉ ra những gì có thể thay vì chỉ cần thực hiện một tuyên bố. Thợ cơ khí không cho bạn biết "Có thứ gì đó với ô tô." khi anh ta đưa cho bạn chìa khóa. Ít nhất không phải là tốt nhất. – cynicaljoy

+0

Không có lỗi cú pháp. Tôi nghĩ ý định là tạo ra một chức năng riêng. (Phải không?) – attack

+0

@cynicaljoy, bài đăng gốc của bạn có lỗi cú pháp. Tôi đã thử nó trên www.jsfiddle.net. Tôi đã đưa ra đề xuất. Hơn nữa, thực tế là tôi đã cung cấp câu trả lời cho thấy ý định của tôi là * hữu ích *. Thật không may, có vẻ như điều này không đạt tiêu chuẩn của bạn. –

1

Sử dụng: handleWindowResize.call (this) Thay vào đó Of: handleWindowResize()

này sẽ thay đổi phạm vi.

1

Có vẻ như bạn đang đến từ một ngôn ngữ khác và cần có ý tưởng vững chắc về cách các nhà thầu hoạt động trong JS.

Bạn có this.name=function(){} cho một hàm và khai báo chức năng cho một hàm khác. Có lý do nào bạn đang sử dụng new function cho đối tượng Cơ sở không? Thực hiện new Base.init() dường như không hoàn toàn đúng. Constructor đang tạo một đối tượng mới, nhưng bạn đang loại bỏ nó, và chỉ sử dụng hàm tạo để thực thi mã lệnh bắt buộc? Bạn không thực thi Base, vì vậy nó có thể chỉ là một đối tượng theo nghĩa đen.

Tôi thực sự khuyên bạn nên xem các bài viết của Doug Crockford về thừa kế và các đối tượng trong JS. Câu hỏi SO này nói về một số kỹ thuật tạo đối tượng khác. Hãy thử tìm kiếm The Good Parts của Crockford. What is happening in Crockford's object creation technique?

Tôi đã loại bỏ nội dung canvas vì tôi chưa từng làm việc với canvas. Điều này sẽ thực thi mà không có lỗi.

<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> 
+0

Trong khi điều này làm việc và thậm chí là một matthew hack Câu trả lời của -manela vẫn cung cấp cho tôi hiệu quả mong muốn. Tôi không muốn có một phương thức 'init()' cồng kềnh. Tôi có thể thấy bạn đang đi đâu và tôi thích hiệu trưởng Tôi không biết cách làm cho nó hoạt động chính xác. Và nó có thể giải quyết xung quanh nhà xây dựng không đúng. – cynicaljoy

+0

@cynicaljoy Tôi nghĩ rằng bạn đang quá khó khăn với bản thân mình (bối cảnh trong JS là khó khăn), và việc sử dụng var self = đây là phổ biến, không hacky cả. Kiểm tra bài đăng này, trong đó cho thấy các mô hình Cole được đề xuất nhưng không có hàm init toàn bộ bao gồm: http://www.wait-till-i.com/2007/07/24/show-love-to-the-module -pattern/ – attack

+0

Bây giờ tôi đang lên một cái gì đó giống như những gì Cole đề nghị nhưng tôi không thể có được this.canvas để trở về bên trong phương thức 'handleWindowResize' khi được kích hoạt bởi trình lắng nghe sự kiện. Nếu tôi sử dụng 'this.handleWindowResize()' thì nó hoạt động. – cynicaljoy