Javascript吊装:调用x和window.x之间的区别

时间:2015-09-16 10:10:34

标签: javascript hoisting

有人能解释下面情景中的提升行为吗?

alert(x);
var x = 10;

Result: alert-undefined

在下面的例子中,x未使用' var'来定义。关键字 - 因此附加到全球范围。

alert(x);
x = 10; // not given a var

Result: error

如果我们用window.x替换x,我们会收到未定义的警告!

alert(window.x); // calling the variable with window namespace
x = 10; // not given a var

Result: alert-undefined

你能解释为什么用变量名(x)和窗口名称空间(window.x)调用变量(附加到全局作用域)是不同的吗?

4 个答案:

答案 0 :(得分:4)

术语"吊装"经常被误解为意味着某些陈述被移到其执行上下文的顶部,这不是发生的事情以及应该避免该术语的原因。

实际发生的是首先处理所有声明,因此在执行任何代码之前,使用 var (以及由函数声明创建的任何函数)声明的任何变量都存在。然后代码执行开始。

因此,在执行任何代码之前(根据ECMA-262)创建变量 x 并为其分配值 undefined ,然后在执行期间,可以分配它一些价值。

所以在:

的情况下
alert(x);
x = 10;
调用 alert 时,

x 存在但尚未分配 undefined 以外的值。

在:

alert(window.x);
x = 10;
未声明

x ,因此在调用 alert 时它不存在,因此出错。在警报之后(如果代码保持运行),对 x 的赋值将创建名为 x 的全局(浏览器中的窗口)对象的属性并为其赋值10。

在:

window.x

ECMAScript的一个怪癖是全局变量也可用作全局对象的属性。表达式{{1}}尝试读取窗口对象的 x 属性。由于不存在此类属性,因此返回 undefined 。然后下一个语句将 x 创建为全局变量,因此 window.x 现在存在,其值为10.

答案 1 :(得分:3)

var x将变量提升到它有效的整个范围内,因此名称 x可用且在范围内的任何位置都有效。其初始值为undefined,它仅在警报后接收其值。

如果是普通x,则变量不会被挂起,因为没有var,所以冒泡到window并且它的创建只发生在行x = 10,它位于警报之后,表示该变量在您尝试提醒时完全未定义且无效。

任何对象的任何不存在的属性都会返回undefined,因此在未设置该属性时测试window.x会按预期返回undefined。这就是您在Javascript中进行会员资格测试的方式:检查特定属性是否等于undefined

答案 2 :(得分:0)

在第一种情况下,id被提升,因此当您调用它时,var x确实存在(即使值未定义)

在第二种情况下,当你说x时,你实际上是在说y = 10,所以根本就没有提升,这就是为什么它根本找不到变量并给你一个错误。

答案 3 :(得分:0)

alert(x);
var x = 10;

将被视为

var x;
alert(x);
x = 10;

因此,在alert x时,undefined的值为default;

alert(x);
x = 10;

将被视为

alert(x);
x = 10; // If this line runs in use strict mode then this line will throw error otherwise in non strict mode x will be added to global object ie. window

因为throw error x undefined alert alert(window.x); x = 10; alert(window.x); x = 10;

undefined

将被视为

window

提醒会提醒object,因为xalert,并且在undefined x = 10; x时没有名为global object的属性}} 之后,non strict mode行会在throw error中添加strict modeNSURLRequestReturnCacheDataElseLoad,如果在var url = NSURL(string: "http://visia-ontwikkeling.nl/polen/pages.php?page=information_point") let requestObj = NSURLRequest(URL: url!, cachePolicy: NSURLRequestCachePolicy. ReturnCacheDataElseLoad, timeoutInterval: 5) webViewLabel.loadRequest(requestObj) <{p}},则<!doctype html> <html> <head> <meta charset="utf-8"> <title>Untitled Document</title> <script src="/js/jquery/jquery-1.11.2.min.js"></script> <script> $(document).ready(function(){ $("#phone").keyup(function() { var number = $("#phone").val(); $.ajax({ url: "/processes/process-data.php", type: 'POST', data: 'number='+number, cache: false, }).done(function( html ) { $('#results').html(html); }); }); }); </script> </head> <body> <form> <table width="400" border="0" cellspacing="0" cellpadding="5"> <tr> <td>Phone #:</td> <td><input type="text" name="phone" id="phone"></td> </tr> <tr> <td>&nbsp;</td> <td>&nbsp;</td> </tr> <tr> <td colspan="2"><div id="results"></div></td> </tr> <tr> <td colspan="2" align="center"><input name="submit" type="submit" value="Submit"></td> </tr> <tr> <td>&nbsp;</td> <td>&nbsp;</td> </tr> </table> </form> </body> </html> 会添加<?php require ('conn.php'); try { $val = $_POST['number'].'%'; $sql="SELECT * FROM phones WHERE phonenumber LIKE :val"; $stmt = $conn->prepare($sql); $stmt->bindParam(':val', $val, PDO::PARAM_STR); $stmt->execute(); $row = $stmt->fetch(PDO::FETCH_ASSOC); $totalRows = $stmt->rowCount(); } catch (PDOException $e) { die("Could not update the table: " . $e->getMessage()); } ?> <?php do { ?> <label><input type="radio" name="phoneno" value="<?php echo $row['phonenumber'] ?>"><?php echo $row['firstname'] ?> <?php echo $row['lastname'] ?> - <?php echo $row['phonenumber'] ?></label><br> <?php } while ($row = $stmt->fetch(PDO::FETCH_ASSOC)); ?>