2012-01-19 33 views
10

HTML:var x = x || "Val mặc định" không nhận được thiết lập đúng nếu x được định nghĩa ở trên nó

<script type="text/javascript"> 
    var x = "overriden"; 
</script> 
<script src="myjs.js"></script> 

myjs.js:

$(document).ready(function(){ 
    var x = x || "default val"; 
    alert(x); // this alerts "default val" and not "overriden" 
}); 

Đối với một số lý do, x được kết thúc như "default val" và không phải "overriden", thậm chí tho tho ban đầu tôi sẽ đặt nó thành "overriden" trước khi tôi thậm chí bao gồm tham chiếu tập lệnh vào myjs.js.

Bất kỳ ý tưởng nào về lý do tại sao điều này xảy ra? Tôi đang cố gắng để kích hoạt trang lưu trữ để thiết lập một ghi đè cho một biến được sử dụng trong một tập tin js bao gồm, nếu không sử dụng val mặc định.

+0

Chỉ cần sử dụng 'var y = x || ... '. – kennytm

+0

có thể xóa từ khóa 'var' của khai báo đầu tiên? –

Trả lời

8

Những gì bạn có sau khi biến tuyên bố treo được áp dụng:

var x; 
x = 5; 

$(document).ready(function(){ 
    var x; 
    x = x || "default"; 
}); 

Nó nhìn vào gần nhất x và nhìn thấy giá trị của nó là undefined đó là một giá trị falsy, vì vậy x được thiết lập để "default".


Bạn sẽ là tốt nếu họ trong phạm vi tương tự, bởi vì tờ khai luôn treo trên bài tập như vậy:

var x = 5; 

var x = x || "default"; 

Thực sự là chỉ

var x; 

x = 5; 
x = x || "default"; 

này đã được đề xuất đó là hoàn toàn vô nghĩa:

$(document).ready(function(){ 
    x = x || "default"; 
}); 

Nó sẽ ném một ReferenceError nếu x không được xác định.


Vì vậy, hoặc làm việc kiểm tra trong phạm vi tương tự hoặc làm điều gì đó như:

$(document).ready(function(){ 
    var x = window.x || "default"; 
}); 

sở hữu không hợp lệ đọc không gây ra một ReferenceError nhưng chỉ trả undefined để thay thế.

+0

đánh dấu câu trả lời này vì một số câu trả lời khác được đề xuất 'var y = x || "mặc định" 'mà bạn đã đề cập" Nó sẽ ném một tham chiếu lỗi nếu x không được xác định. " –

3

Bạn đang sử dụng từ khóa var ở cả hai vị trí. Hãy thử:

x = x || "default val"; 

https://developer.mozilla.org/en/JavaScript/Reference/Statements/var

Từ liên kết ở trên:

Phạm vi của một biến khai báo với var là chức năng kèm theo hoặc, đối với các biến khai báo bên ngoài một chức năng, phạm vi toàn cầu (trong đó bị ràng buộc với đối tượng chung).

1

Vì bạn lại tuyên bố một số mới var x bên trong document.ready() là phạm vi khác so với toàn cầu. Hãy thử điều này

$(document).ready(function(){ 
    x = x || "default val"; 
    alert(x); // this will now alert "overriden" 
}); 
4

Các var x trong hàm được chuyển vào $(document).ready() được giấu phạm vi toàn cầu x biến.

Nếu bạn chỉ sử dụng x = x || "default val";, thì biến toàn cục sẽ bị ghi đè. Tuy nhiên, nó thực sự là một ý tưởng tồi để có các biến toàn cục.

1

x không được xác định trong phạm vi chức năng document ready.

var x đang chuẩn bị biến với giá trị undefined, vì vậy nó sẽ không nhận được nó từ phạm vi cửa sổ.

Hãy thử var x = x || window.x || "default val"; để thay thế.

+0

x sẽ đưa ra lỗi tham chiếu nếu tôi không định nghĩa nó lần đầu tiên, fyi. –

1

Vì bạn đã tuyên bố với một biến không nhận được đối tượng được xác định trên toàn cầu từ html. Hãy thử xóa var và xem bạn có nhận được kết quả khác hay thay đổi biến trong hàm thành một chữ khác.

Khi bạn sử dụng var trong một hàm, phạm vi của var đó chỉ là hàm. Vì bạn đã định nghĩa biến x hai lần khi bạn đang so sánh nó đang cố gắng sử dụng biến từ bên trong hàm.

Nếu bạn dự định giữ câu lệnh var, bạn sẽ cần phải thay đổi tên biến hoặc cách bạn đang gọi toàn cầu x thành window.x. Các tùy chọn khác chỉ là để thả var từ chức năng.

0

Bạn đang khai báo var x trong chức năng tạo bộ nhớ cục bộ cho x và ẩn các giá trị trước đó.

Gọi điện thoại là var y hoặc làm như karim79 đề xuất.

+0

Tôi thực sự muốn chấp nhận điều này, nhưng, nếu tôi làm var 'y = x || "mặc định" ', sau đó js ném một lỗi nói rằng x là không xác định. –

1

Các x tạo ra trên dòng này:

var x = x || "default val"; 

... là địa phương để các chức năng nó được định nghĩa trong (tức là nó shadows toàn cầu x).

Xóa var trước đó sẽ khiến cả hai tên x tham chiếu cùng biến toàn cầu, nhưng đây thường là ý tưởng tồi. Từ trang Wikipedia được liên kết trước đây:

Điều này có thể không rõ ràng biến nào sử dụng tên biến tối nghĩa là sử dụng tiếp theo.

0

Số thứ hai là địa chỉ của hàm đó và không giống như window.x (đó là những gì bạn đã xác định trong khối trước).

0

từ khóa var nghĩa là bạn vừa tạo biến cục bộ. Vì vậy, về cơ bản những gì đang xảy ra là:

  1. Bạn khai báo (trong khối đầu tiên của bạn) x là "ghi đè"

Memory:

x -> "overriden" 
  1. Bạn đặt callback để tài liệu .ready

Bộ nhớ:

x -> "overriden" 

(sau khi tài liệu được nạp) 3. bạn chạy chức năng ẩn danh của bạn, initialising x với var

Memory:

x->"overriden" 
[IN SCOPE] 
anonymous_function.x -> "default_value" 
[/SCOPE] 

"NHƯNG WAIT", có lẽ bạn nói rằng, "mã tôi viết là var x= x || "default var" vì vậy điều gì sẽ xảy ra là local_x=global_x || "default value, phải không?

Không may mắn thay Javascript không hoạt động như thế. Trong javascript, chúng ta có phạm vi chức năng, thay vì phạm vi khối được sử dụng rộng rãi hơn. Vì vậy, khi bạn viết:

f=function(){ 
    var x=y || "default value"; 
    var y=3; 
    alert(x); 
} 

những gì sẽ được giải thích trong javascript là:

f=function(){ 
    var x; 
    var y; 
    x=y || "default value"; 
    y=3; 
    alert(x); 
} 

để chạy y=10; f(); sẽ cung cấp cho bạn "Giá trị mặc định" trên dấu nhắc.


Vì vậy, cất cánh của bạn var sẽ làm việc để khắc phục vấn đề của bạn ở đây, nhưng hãy nhớ nói chung là tất cả các khai báo biến của bạn được thực hiện "vào đầu" của một hàm, vì vậy phạm vi được ngay lập tức thay đổi khi bước vào một chức năng .

Các vấn đề liên quan