js中变量注意事项

变量声明

ECMAScript中的变量是弱类型的(同一个变量可以保存任何数据类型)。

  1. 通过var关键字来定义变量;
  2. 未经过初始化的变量的默认值是undefined;
  3. 使用var声明的变量是当前作用域的局部变量(如果在函数中定义一个变量,在函数执行完成后该变量就会被销毁);
  4. 没通过var关键字声明的变量会被自动声明为全局变量。
 1     // 3
 2     var iNum;
 3     console.log(iNum); // undefined
 4
 5     // 4
 6     function fnTest(){
 7       var sMsg = ‘hum‘;
 8       console.log(sMsg); // hum
 9     }
10     fnTest();
11     console.log(sMsg); // sMsg is not defined
12
13     // 5
14     function fnTest1(){
15       sMsg1 = ‘hum‘; //  未通过var关键字声明的变量
16       console.log(sMsg1); // hum
17     }
18     fnTest1();
19     console.log(sMsg1); // hum 在函数外部能访问

NOTE:为声明的变量只能进行typeof和delete操作,其他任何操作都会抛出错误。

1     console.log(typeof iName); // undefined
2     console.log(delete iName); // true(居然返回true)
3     console.log(iName); // iName is not defined

严格模式注意事项:

  1. 给未经声明的变量赋值会抛出ReferenceError错误;
  2. 声明名为eval和arguments的变量会导致语法错误;
  3. 给未声明的变量进行delete操作会导致语法错误。

变量类型

ECMAScript由三种简单数据类型(Boolean、Number、String)、两种特殊类型(Undefined、Null)和一种复杂数据类型(Object)组成。

typeof操作符检测变量数据类型返回的结果类型:

  1. undefined(变量未定义或定义了未赋值);
  2. boolean(布尔值);
  3. string(字符串);
  4. number(数值);
  5. object(对象或null);
  6. function(函数);

变量作用域

要深入理解作用域我们先来看看执行环境和作用域链。

每个执行环境都有一个与之关联的变量对象,环境中定义的所有变量和函数都保存在这个对象中(该对象存在后台,代码无法访问)。

全局执行环境:ECMAScript的宿主环境(浏览器就是window),全局执行环境在程序退出时才会被销毁。

局部执行环境:每个函数都有自的执行环境,函数执行时,函数会被推入一个环境栈中。函数执行完成后,环境栈被弹出,把控制权交给之前的执行环境。

代码进入一个执行环境时会创建变量对象的一个作用域链。该作用域链的前端是当前执行环境的变量对象,下一个是外部执行环境的变量对象,一直到全局执行环境的变量对象。

标识符解析是沿着作用域链一级一级向上检索,直到找到该标识符为止(如果没有找到就会发生错误)。

 1     var iNum1 = 1;
 2
 3     function fnOuter(){
 4       var iNum2 = 11;
 5
 6       function fnInner(){
 7         var iNum3 = 111;
 8
 9         console.log(iNum1); // 作用域链查找:fnInner(无)->fnOuter(无)->window(1)
10         console.log(iNum2); // 作用域链查找:fnInner(无)->fnOuter(11)
11         console.log(iNum3); // 作用域链查找:fnInner(111)
12       }
13       fnInner();
14
15       console.log(iNum1); // 作用域链查找:fnOuter(无)->window(1)
16       console.log(iNum2); // 作用域链查找:fnOuter(11)
17       console.log(iNum3); // 作用域链查找:fnOuter(无)->window(无)报错
18     }
19     fnOuter();
20     console.log(iNum1); // 作用域链查找:window(1)
21     console.log(iNum2); // 作用域链查找:window(无)报错
22     console.log(iNum3); // 作用域链查找:window(无)报错

变量声明提升

ECMAScript进入一个执行环境会把执行环境中所有的变量的声明提升到当前作用域的最前端。

表现一:变量声明提升

1     var iNum = 1;
2     function fnTest(){
3       console.log(iNum); // undefined
4       var iNum = 11;
5     }
6     fnTest();

上面的代码输出了undefined。原因是当执行函数fnTest时会检索函数中所有变量的声明并优先执行。上面的代码就类似于下面的代码。

    var iNum = 1;
    function fnTest(){
      var iNum; // **变量声明提升
      console.log(iNum); // undefined
      iNum = 11;
    }
    fnTest();
时间: 2024-11-15 06:31:16

js中变量注意事项的相关文章

js中变量名提升和函数名提升

首先,js中变量没有块级作用域,但是有函数作用域,即只有函数可以约数变量的作用域. 并且,函数的实质也是一个变量,所以可以改变它的值,即赋值.所以变量名提升和函数名提升非常相像. 1.变量名的提升发生在函数内部.看下面的例子.说明:第一个因为弹出undefined,相当于在上面定义了var num;因为函数内部,定义了var num=20:就相当于在一开始定义了var num;这就是变量名的提升. var num = 10; function func() { alert(num); //und

PHP和JS中变量作用域

一,PHP中变量作用域 对于大多数PHP的变量只有一个作用域.在用户自定义函数里采用局部变量作用域.所有的函数内使用的变量被设置为局部变量.例如: <?php $a=1; function test() { echo $a; } test(); ?> 这段程序不会输出任何的东西因为echo语句要输出局部变量 $a ,而函数内的 $a 从未被赋过值.你可能注意到和C语言有点小小的区别,C中全局变量可以直接在函数内引用,除非它被一个局部变量所覆盖.因为这使得人们可能不注意修改了全局变量的值.在PH

js中变量的声明

大家都知道js中变量的声明是要提前的,以下有4个例子: 1.if(!"t" in window){ var t = 1; } alert(t);答案是undefined,为什么呢,就是因为变量声明提前了,所以t是在window对象里面的,但是没有走下面的判断,所以并没有赋值,答案就是undefine 2.var num = 100; function fn(){ var num = num + 1; return num; } falert(n());答案依然是NaN,因为在函数体内部

JS中变量的存储

JS中的变量是保存在栈内存中的 基本数据类型的值直接在栈内存中存储: 值与值之间是独立存在的,修改一个变量不会影响其他变量: var a=20; var b=a; a++; 对象是保存到堆内存中的,每创建一个新的对象,就会在堆内存中开辟一个新的空间: 而变量保存的是对象的内存地址(对象的引用),如果两个变量保存的是同一个对象引用,当一个变量修改属性是,另一个也会受到影响: var obj1=new Object(); obj1.name="mike"; var obj2=obj1; o

js中变量base64加密传输

首先对base64进行定义: var Base64 = { _keyStr : "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=", encode : function(e) { var t = ""; var n, r, i, s, o, u, a; var f = 0; e = Base64._utf8_encode(e); while (f < e.length) { n

js中变量的连续赋值

下面就是这个经典案例: var a = {n: 1}: var b = a; a.x = a = {n: 2}: console.log(a);console.log(b); console.log(a.x); console.log(b.x): 我们先来看一下普通连续赋值,即:变量赋值的类型是数据类型值 var a=3; var b=a=5; console.log(a); console.log(b); 一般来说,等号赋值的方向是从右至左,那么上面的代码等同于下面这段代码,那么我们就用下面这

关于js中变量声明和作用域的理解

1. var是声明一个变量:虽然声明了这个变量,但在存入值之前,它的初始值是 undefined:2.全局变量:拥有全局作用域,在js代码中的任何地方都是有定义的:3.局部变量:在函数内声明的变量只在函数内有定义,作用域是局部的,只在函数内有定义:4.全局作用域编写代码时可以不写var,但声明局部变量时必须使用var语句;5.在函数体内,局部变量的优先级高于同名的全局变量.如果局部变量和全局变量同名,那么全局变量会被局部变量所遮盖:但全局变量的值不会改变:6.作用域链查找规则:自上而下(一个或多

js中变量含(参数、数组)作用域传递问题

js没有块级作用域(你可以自己闭包或其他方法实现),只有函数级作用域和全局作用域,函数外面的变量函数里面可以找到使用,函数里面的变量外面无法访问到. 写这个是因为ES6中的一个例子开始的.首先看下例子 var a = []; for (var i = 0; i < 10; i++) { a[i] = function () { console.log(i); }; } a[6](); // 10 var a = []; for (let i = 0; i < 10; i++) { a[i] =

关于JS中变量提升的规则和原理的一点理解

????关于变量提升,以前在一些教程和书籍上都听到过,平时开发中也知道有这个规律,但是今天突然在一个公开课中听到时,第一反应时一脸懵逼,然后一百度,瞬间觉得好熟悉啊,差点被这个概念给唬住了,不信我给你看个栗子,你也会恍然大悟的: (function(){ console.log(v); var v = 'I love you'; console.log(v); })() // undefined I love you ????这就是一个典型的变量提升的例子了,规则是怎样的呢,我的理解是在一个作用