2010-06-23 47 views
10

bạn có biết cách tốt để kiểm tra xem biến có phải là đối tượng cửa sổ trong javascript không? Tôi đã thử với:Kiểm tra Javascript nếu biến là cửa sổ

var variable=window; 
Object.prototype.toString.call(variable); 

Trong Firefox nó trả "[object Window]" nhưng trong IE "[object Object]" vì vậy đó là không đúng cách. Bạn có biết cách kiểm tra chính xác không?

+0

bạn có thể chỉ cần làm một thử nghiệm tương đương với 'window'? '(somevar === window)? 'yes': 'no'' –

+0

Nhưng nếu đó là một cửa sổ iframe thì nó sẽ không hoạt động. – mck89

+0

Tôi tò mò, tại sao bạn cần phải làm điều này? –

Trả lời

10

Có, nhưng tôi cần một cách để kiểm tra tất cả các cửa sổ không chỉ là hiện tại một

Có một vài cách bạn có thể làm điều này. Phương pháp đơn giản nhất là kiểm tra một hoặc hai thuộc tính đã biết trên đối tượng cửa sổ. Ngoài ra còn có các self bất động sản - cho mỗi cửa sổ, bạn có thể kiểm tra self tài sản tương đương với các đối tượng cửa sổ:

myvar.self == myvar; 
window.self == window; 
frameElement.contentWindow.self == frameElement.contentWindow; 
+0

Cảm ơn bạn! – mck89

+1

'self' có thể được ghi đè và thường được sử dụng như một tên biến để giữ lại ngữ cảnh. – zzzzBov

+0

@zzzzBov: Vậy, cái gì? Hầu hết các thuộc tính có thể được ghi đè, nhưng bạn hiếm khi thấy điều này xảy ra khi cố gắng * "giữ lại ngữ cảnh" * vì nó không xảy ra trong phạm vi toàn cầu và bất kỳ nhà phát triển tự tôn trọng nào sẽ khai báo với 'var' ở bất kỳ nơi nào khác. Miễn là bạn đề cập đến 'window.self' và không chỉ là' self', bạn sẽ ổn thôi. Nếu nó quan trọng đối với bất cứ ai, tôi cho rằng họ có thể sử dụng 'window.window' thay vì' window.self', nếu họ muốn. Nó được bảo vệ khỏi bị ghi đè trong hầu hết các trình duyệt hiện đại. –

1
variable == window 

Ai đó vẫn có thể xác định biến cục bộ được gọi là window. Tôi không chắc chắn có một cách nào đó có khả năng đàn hồi cho tất cả các shenanigans như vậy. Ai đó có thể tạo một đối tượng sao chép hầu hết các thuộc tính và chức năng của cửa sổ, bao gồm toString.

1
if(variable == window) 

Tất nhiên chỉ kiểm tra nếu đối tượng biến là cửa sổ này (tức là cửa sổ của tài liệu đang thực thi javascript).

Ngoài ra, bạn có thể thử một cái gì đó như thế này:

if(variable.document && variable.location) 

Và kiểm tra sự tồn tại của một vài lĩnh vực cửa sổ và/hoặc chức năng, do đó bạn là khá chắc chắn rằng nó là một cửa sổ ...

2

làm thế nào về chỉ:

isWindow = variable === window; 

Các triple-bằng ngăn gõ ép buộc mà nếu không sẽ làm cho điều này khó khăn hơn nhiều việc phải làm.

+2

Có nhưng tôi cần một cách để kiểm tra mọi cửa sổ không chỉ cửa sổ hiện tại. – mck89

+0

Kiểm tra loại nghiêm ngặt là không cần thiết khi so sánh cùng một đối tượng. –

0

Kể từ window là một biến toàn cầu và biến toàn cục là tài sản của đối tượng toàn cầu, window.window sẽ bằng window . Vì vậy, bạn có thể kiểm tra:

if (mysteryVariable.window == mysteryVariable) 
    ... 

Vấn đề là điều này có thể bị lừa nếu chúng ta có một đối tượng như thế này:

var q = {}; 
q.window = q; 

Nếu đó là không có khả năng, sau đó bạn có thể sử dụng mã này.

2

Sau khi toying xung quanh với nhiều lựa chọn, tôi tin rằng đây là phương pháp chính xác nhất để phát hiện nếu một đối tượng là một cửa sổ trình duyệt chéo:

(function() { 
    "use strict"; 
    var wStr; 
    wStr = Object.prototype.toString.call(window); 
    function isWindow(arg) { 
     var e, 
      str, 
      self, 
      hasSelf; 
     //Safari returns DOMWindow 
     //Chrome returns global 
     //Firefox, Opera & IE9 return Window 
     str = Object.prototype.toString.call(arg); 
     switch (wStr) { 
     case '[object DOMWindow]': 
     case '[object Window]': 
     case '[object global]': 
      return str === wStr; 
     } 
     ///window objects always have a `self` property; 
     ///however, `arg.self == arg` could be fooled by: 
     ///var o = {}; 
     ///o.self = o; 
     if ('self' in arg) { 
      //`'self' in arg` is true if 
      //the property exists on the object _or_ the prototype 
      //`arg.hasOwnProperty('self')` is true only if 
      //the property exists on the object 
      hasSelf = arg.hasOwnProperty('self'); 
      try { 
       if (hasSelf) { 
        self = arg.self; 
       } 
       delete arg.self; 
       if (hasSelf) { 
        arg.self = self; 
       } 
      } catch (e) { 
       //IE 7&8 throw an error when window.self is deleted 
       return true; 
      } 
     } 
     return false; 
    } 
}()); 

tôi sẽ cần phải thực hiện một số chặt chẽ hơn đơn vị thử nghiệm, do đó, hãy cho tôi biết về bất kỳ sự mâu thuẫn nào phát sinh.

+0

Tôi đã cập nhật câu trả lời của bạn vì có lỗi, sau đó tôi đã thử nghiệm và dường như nó hoạt động, nhưng tôi nghĩ rằng phần đầu tiên quá hạn chế vì hầu như mọi trình duyệt đều có cách riêng để chuyển đổi cửa sổ thành chuỗi và có thể có hơn 3 biến thể. – mck89

+0

@ mck89, tôi chủ yếu quan tâm đến 5 người lớn: Firefox, Chrome, Safari, Opera và IE. Sẽ rất tuyệt nếu các trình duyệt được chuẩn hóa bằng cách sử dụng ''[object Window]'', tuy nhiên đặc tả ECMAScript5 [cho phép mỗi trình duyệt chọn giá trị riêng của nó cho thuộc tính '[[Class]] của đối tượng toàn cục] (http: //es5.github.com/#x15.1). Trong ý nghĩa đó, có, nó là một thực hiện tương đối hạn chế, tuy nhiên tôi nghĩ rằng nó nhiều hơn đàn hồi hơn kiểm tra 'arg.self == arg', mà dễ dàng bị lừa. – zzzzBov

+0

Tôi thực sự khen ngợi nỗ lực của bạn, nhưng tôi tự hỏi ai cần phải nghiêm khắc này. Có lẽ một thư viện sẽ sử dụng nó, nhưng ngay cả jQuery cũng nghĩ rằng 'if (obj && typeof obj ===" object "&&" setInterval "trong obj)' là đủ thích hợp. Khi nào có nhu cầu ai đó viết 'o.self = o', và có khả năng ai đó sẽ cần phải kiểm tra xem đó là một đối tượng 'cửa sổ'? Đối với khả năng phục hồi, bạn sử dụng '" sử dụng nghiêm ngặt "' làm cho hàm thậm chí còn ít đàn hồi hơn 'arg.self === arg' vì một * TypeError * sẽ được ném khi bạn xóa thuộc tính' self' bằng 'Configurable' thuộc tính được đặt thành 'false'. –

4

Tìm thấy mã này trong mã nguồn AngularJS. Một lót và đập vào mục tiêu.

return variable && variable.document && variable.location && variable.alert && variable.setInterval; 
+0

Khi biến là không xác định điều này sẽ ném ngoại lệ (như hàm trả về undefined thay vì true/false): instanceof Window là phương pháp đơn giản nhất để kiểm tra. Để sử dụng mã AngularJS này, hãy bọc nó trong try {} catch hoặc with (typeof variable! == 'undefined') –

0
var x = new Window(); 
x instanceof Window 
var y = [] 
y instanceof Window 
+2

Ít người dùng biết, nhưng chúng tôi đã mở một cửa sổ mà họ không biết ... – redolent

0
let isWindowObj = (anObject instanceof Window); 
Các vấn đề liên quan