JavaScript声明和未声明变量之间的主要区别是什么? delete运算符不适用于声明的变量吗?
var y = 43; // declares a new variable
x = 42;
delete x; // returns true (x is a property of the global object and can be deleted)
delete y; // returns false (delete doesn't affect variable names)
为什么会这样?全局声明的变量也是window对象的属性,为什么不能删除呢?
答案 0 :(得分:26)
存储和访问它们的机制是相同的,但JavaScript在某些情况下会根据configurable
属性的值(下面描述)对它们进行不同的处理。在常规使用中,它们应该表现相同。
以下是声明的和未声明的全局变量的一些比较。
var declared = 1; // Explicit global variable (new variable)
undeclared = 1; // Implicit global variable (property of default global object)
window.hasOwnProperty('declared') // true
window.hasOwnProperty('undeclared') // true
window.propertyIsEnumerable('declared') // true
window.propertyIsEnumerable('undeclared') // true
window.declared // 1
window.undeclared // 1
window.declared = 2;
window.undeclared = 2;
declared // 2
undeclared // 2
delete declared // false
delete undeclared // true
delete undeclared // true (same result if delete it again)
delete window.declared // false
delete window.undeclared // true (same result if delete it yet again)
delete window.undeclared // true (still true)
声明和未声明的全局变量都是window
对象(默认全局对象)的属性。两者都不是通过原型链从不同的对象继承而来。它们都直接存在于window
对象中(因为window.hasOwnProperty
两者都返回true
。)
对于声明的全局变量,configurable
属性为false
。对于未声明的全局变量,它是true
。可以使用getOwnPropertyDescriptor
方法检索configurable
属性的值,如下所示。
var declared = 1;
undeclared = 1;
(Object.getOwnPropertyDescriptor(window, 'declared')).configurable // false
(Object.getOwnPropertyDescriptor(window, 'undeclared')).configurable // true
如果属性的configurable
属性为true,则可以使用defineProperty
方法更改属性的属性,并且可以使用delete
运算符删除属性。否则,无法更改属性,并且无法以此方式删除属性。
在non-strict mode中,如果属性是可配置的,delete
运算符将返回true
,如果属性不可配置,则返回false
。
声明的全局变量
window
)delete
运算符未声明的全局变量
window
)delete
运算符答案 1 :(得分:1)
主要区别在于您在函数内声明变量。如果在函数内声明变量时使用var
,则该变量将成为局部变量。但是,如果您不使用var
,那么无论您在何处声明它(在函数内部或外部),该变量都将成为全局变量。
答案 2 :(得分:1)
当通过 JavaScript 中的变量声明创建任何变量时,这些属性是使用“ DontDelete ”属性创建的,这基本上意味着您创建的变量无法使用“删除”删除“表达式。默认情况下,所有函数,参数和函数参数都是使用此DontDelete属性创建的。您可以将DontDelete视为旗帜。
var y = 43;
delete y; //returns false because it is has a DontDelete attribute
而未声明的作业不会设置任何属性,例如 DontDelete 。因此,当我们对此未声明的变量应用 delete 运算符时,它将返回true。
x = 42;
delete x; //returns true because it doesn't have a DontDelete attribute
属性赋值和变量声明之间的区别 - 后者设置DontDelete,而前者不设置。这就是为什么未声明的赋值会创建一个可删除的属性。
答案 3 :(得分:0)
delete仅对对象的属性有效。它对变量或函数名称没有影响。
在你的情况下x = 42;声明变量X并使其成为Global对象的属性。所以它返回true。
并且var y = 43;声明一个全局变量,它不是任何对象的一部分,因此返回false。