JS 中 var a 与非 var a 的区别

前段时间开始了JS的学习,第一个重要的知识点就是变量声明及变量声明提升。关于变量声明,有这样两种代码:

var a = 1;
console.log(a)  // 1
a = 1 ;
console.log(a)  // 1

var a = 1a = 1都没有报错的,那么这两者区别在哪里呢?

首先,var语句用于声明变量,而不使用var直接赋值,则会创建一个全局变量,该变量是全局对象的一个属性。

如上面第2段代码,在全局作用域下,对非声明的变量a赋值,会创建一个全局变量a,在浏览器中,awindow对象的一个属性。

以上我们了解了非var a的基本构成,他们之间还有什么区别呢?

  • 非声明变量没有变量提升,且只有在执行赋值操作时才被创建
console.log(a)   // ReferenceError: a is not defined 
a = 1 
console.log(a)   // 1
  • 声明变量作用域限制在其声明位置的上下文中,非声明变量在创建后是全局的
function f() {
  a = 1            
  var b = 2
}

f()  //执行方法,创建变量

console.log(a)  // 1
console.log(b)  // ReferenceError: b is not defined

//这里可以看出,声明变量的作业域是有限制的,而非声明变量在创建后会成为全局变量
  • 声明变量是它所在上下文环境的不可配置属性(non-configurable property),非声明变量是可配置的(例如非声明变量可以被删除)。
a = 2
var b = 2

var testa = Object.getOwnPropertyDescriptor(window, 'a')
var testb = Object.getOwnPropertyDescriptor(window, 'b')


// 在chrome下,使用Object.getOwnPropertyDescriptor方法对a和b 检验

console.log(testa)  // Object {value: 2, writable: true, enumerable: true, configurable: true} 
console.log(testb)  // Object {value: 2, writable: true, enumerable: true, configurable: false}

/* 
Object.getOwnPropertyDescriptor()会返回对应第一个参数的对象的属性描述符(property description),
如果指定的属性不在对象上,会返回undefined,
可以看出在全局作用域下,声明变量和非声明变量都为全局对象window的属性。
其区别是声明变量的configurable为true,非声明变量的configurable为false。
*/


delete(a)  // true     可以删除
delete(b)  // false    不可以删除
console.log(a)  // ReferenceError: a is not defined  
console.log(b)  // 2 

// 根据configurable属性,非声明变量a 可以被操作,而声明变量a不可以

function ccc () {
  c = 1 
}

var ddd = {}
var testc = Object.getOwnPropertyDescriptor(window, 'c')
console.log(testc)  // undefined

ccc()
var testc = Object.getOwnPropertyDescriptor(window, 'c')
var testd = Object.getOwnPropertyDescriptor(ddd, 'c')
console.log(testc)  // Object {value: 1, writable: true, enumerable: true, configurable: true}
console.log(testd)  // undefined

// 确认非声明变量在创建后,为全局对象的属性

参考:

  1. https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Statements/var
  2. https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object/getOwnPropertyDescriptor

你可能感兴趣的:(JS 中 var a 与非 var a 的区别)