<script>
var a=1;//全局环境下,用var声明一个全局变量
var b=function(){a=3}();//函数内的a没有用var声明
alert(a);//a的值为3
alert(delete a)//false
</script>
“如果你没有使用严格模式并给一个未声明的变量赋值的话,JS会自动创建一个全局变量。以这种方式创建的变量,是全局对象的正常可配置属性,并可以删除它们。”--------犀牛书6版,58页。
var b=function(){a=3}() 内的a没有用var声明,那么应该创建一个可配置的全局变量。但是全局环境有一个变量a,并且是用var声明过的。
按照我这个初学者的认识:
var b=function(){a=3}() 内的a应该覆盖掉全局环境下a的值,并且a应该是可用delete删除的。情况a的值确实变为3了,但delete a却不可以,请问这是为什么?谢谢。
首先,上个例子:
好,从例子看以看出,未通过var声明的变量a和通过var声明的变量b,都可以通过this和window访问到,区别是一个可以被delete,一个不可以,下面分析下:
为什么delete的结果不同?
为什么他们都可以被this和window访问到?
下面说说你的例子
“如果你没有使用严格模式并给一个
未声明的变量
赋值的话,JS会自动创建一个全局变量。以这种方式创建的变量,是全局对象的正常可配置属性,并可以删除它们。”--------犀牛书6版,58页。<script>
var a=1;//全局环境下,用var声明一个全局变量
var b=function(){a=3}();//函数内的a没有用var声明
alert(a);//a的值为3
alert(delete a)//false
</script>
var a = 1
已经在全局执行上下文中声明了变量a
,并且赋值为1
. 所以不符合书中描述的条件!var a;
这条语句一执行,window
的属性a
对应的属性描述符对象(property descriptor)就确定了:configurable: false
就意味着 不能删除!js变量的作用域需要涉及到作用域链,如:http://www.cnblogs.com/lhb25/archive/2011/09/06/javascript-scope-chain...
1、函数运行时会有一个执行上下文,函数里用到的变量先去一个叫做活动对象的作用域查找该变量是否在这个类似“堆栈”的作用域链;
2、如果没有,则再去一个叫做全局对象的作用域链查找该变量;
3、每次使用变量都会重复去查找一次这个作用域链,所以为了在循环中提高代码效率,尽量将全局变量赋值给一个局部变量,解决全局变量在反复查找过程中带来的效率(全局作用域链在局部作用域链下面)
function里面的a = 3并没有像你说的那样重新创建一个变量a并且覆盖掉以前的var a;在function里面出现对a的引用,会在函数作用域里面寻找a的定义,没有找到则在函数的作用域链的下一层即global里面寻找。找到a之后对a重新赋值为3。delete的语境等价于var a = 3;delete a;当然是false。如果你把function里面的a换成是c或者其它未定义的变量再delete c,就是true.关于作用域,执行环境的相关部分我建议阅读《Javascript 高级程序设计》的第四章。
因为
a
不是一个隐式声明的变量!MDN delete
所以说
a=3
只是把全局变量的a
给覆盖了!a已经被var声明了,所以是不能够被删除的,但是 var b=function(){a=3}();后面加了一个小括号是怎么回事?匿名函数?
@qianjiahao 已经说的很好了
使用var 是声明变量,声明变量自带不可删除属性,而非var 产生的变量为window的属性,所以可以删除