【JS】 JavaScript语句和声明之var

252 阅读6分钟

篇外之言

前段时间,由于电脑WebStorm软件在Git提交过程中卡机强制退出操作后,将自己电脑里平日对前端的学习痕迹记录差不多“除掉”所剩无几......于是寻思着是否应该将平日所学找个地方记录下,帮助自己加深记忆之外,也方便日后温故而知新呢!

之前在网上查阅资料时,也看到过各社区平台上各种博文基本上都是长篇大论,给人一种很高达上的感觉,总感慨自己这种压根没啥文笔的人,啥时会写出这样的文章啊。而且,接触前端才知道MarkDown标记语言,话说是程序员必会的写作方式,之前也没听过......之前学习要么是word文档记录,要么是手写记录,认为博文是有了一定经验阅历的大佬们学习记录方式。

不过,有幸接触了一些前端圈的过来人或刚接触前端的小伙伴们,平日交流学习的小伙伴说了一番话“......博客是写给自己看的......菜鸟一开始不能写长篇大论的就不能存活了么?菜鸟也要记录,也要成长......不要怕写不好,第一步是写......”让我印象很深刻。没错,业精于勤,荒于嬉,毁于随。尝试开始写,就如小学开始认字写字是一样的道理。话不多说,动起来,动起来,动起来啦!

前言

var 声明语句声明一个变量,并可选地将其初始化为一个值。

1.语法

var name1 [= value1] [, name2 [= value2] ... [, nameN [= valueN]]];

  • nameN:变量名。 可以定义为任何合法标识符。
  • valueN:变量的初始值。 该值可以是任何合法的表达式。默认值为 undefined。

2.描述

变量声明,无论发生在何处,都在执行任何代码之前进行处理。用 var 声明的变量的作用域是它当前的执行上下文,它可以是嵌套的函数,或对于声明在任何函数外的变量来说是全局。

当赋值给未声明的变量, 则执行赋值后, 该变量会被隐式地创建为全局变量(它将成为全局对象的属性)。

声明和未声明变量之间的差异是

  1. 声明变量的作用域限制在其声明位置的上下文中,而非声明变量总是全局的。
function fn({
  a = 1;   // 在严格模式(strict mode)下会抛出 ReferenceError 异常
  var b = 2;
}
fn();
console.log(a); // 打印 "1"
console.log(b); // 抛出 ReferenceError: b 未在 fn 外部声明
  1. 声明变量在任何代码执行前创建,而非声明变量只有在执行赋值操作时才会被创建。
//声明变量情况
var a;
console.log(a);                // "undefined"或""(不同浏览器实现不同)。
//非声明变量情况
console.log(a);                // 抛出ReferenceError。
a = 1;
console.log(a);
  1. 声明变量是它所在上下文环境的不可配置属性,非声明变量可配置的(如非声明变量可以被删除)。
var a = 1;
b = 2;

delete this.a; // 在严格模式(strict mode)下抛出TypeError,其他情况下执行失败并无任何提示。
delete this.b;

console.log(a, b); // 抛出ReferenceError。
// 'b'属性已经被删除。

因存在以上差异,非声明变量将有可能导致意想不到的结果。因此,建议始终声明变量,无论它们是在函数作用域还是全局作用域内。 而且,在 ECMAScript 5 严格模式下,分配给未声明的变量会引发错误。

3.栗子

  • 声明并初始化两个变量:
var a = 0, b = 0;
  • 给两个变量赋值成字符串值:
var a = "string";
var b = a;

// 等效于:
var a, b = a = "string";

注意其中的顺序:

var a = b, b = "string";
console.log(a + b); // "undefinedstring"

上述代码,变量a和变量b在代码执行前就已经被创建,赋值操作是发生在变量创建之后。当执行a = b时,变量b已存在,故不会抛出ReferenceError,且b的值为undefined,因此a被赋值为undefined。接着,b被赋值为string,所以在执行完第一行代码后,a === undefined && b === "string"出现输出结果undefinedstring

  • 多个变量初始化
var a = 0;
function fn(){
  var a = b = 1// a在函数内部声明,b不是!
}
fn();
console.log(a, b); // 0, 1
// a 是全局变量。
// b 是隐式声明的全局变量。 
  • 隐式全局变量和外部函数作用域 看上去像是隐式全局作用域的变量也有可能是其外部函数变量的引用。
var a = 0;             // a 是全局变量,且赋值为0。
console.log(typeof c); // undefined,因为 c 还不存在。

function fun({       // 当函数fun被调用时,
  var b = 2;           // b 被声明成 函数fun 作用域的变量,且赋值为2。
  console.log(a, b);   // 0 2 
  function foo({     // 当函数foo被调用时,
    a = 3;             // 全局变量 a 被赋值为3,不生成全局变量。
    b = 4;             // 已存在的外部函数 b 变量被赋值为4,不生成新的全局变量。
    c = 5;             // 创建新的全局变量 c,且赋值为5。 
  }                      // (在严格模式下(strict mode)抛出ReferenceError)
  foo();               // 调用函数foo时创建了全局变量c。
  console.log(a, b, c);  // 3 4 5
}

fun();                   // 调用函数fun时,内部调用了函数foo。
console.log(a, c);       // 3 5
console.log(typeof b);   // undefined,因为变量 b 是函数 fun 的局部变量。

最后

第一次写记录,如果发现内容有误,欢迎评论指出错误,感谢ing!