认识JavaScript中的变量

JavaScript中的变量有两种类型,一种是基本类型、一种是引用类型。

  • 基本数据类型:Defined,Null,Boolean,Number,String。注意String是属于基本数据类型,这不同于其他高级语言。
  • 引用类型即对象,包括内置对象和自定义对象。

需理解的差异

关于复制

对于基本类型的变量,就是我们印象中对于变量的理解。

var a = "TabWeng";
var b = a;
console.log("a:"+a+", b:"+b);
a = "Weng";
console.log("a:"+a+", b:"+b);

运行结果:

a:TabWeng, b:TabWeng
a:Weng, b:TabWeng

我们来看另一个例子:

var a = new Object();
a.name = "TabWeng";
var b = a;
console.log("a'name:"+a.name+", b'name:"+b.name);
a.name = "Weng";
console.log("a'name:"+a.name+", b'name:"+b.name);

运行结果:

a'name:TabWeng, b'name:TabWeng
a'name:Weng, b'name:Weng

这个结果就不同了,我只修改了 a.name 的值,b.name 的值也跟着发生变化,答案只能是它们的值都指向同一个地方,即它们都指向同一块内存,只要内存的值发生变化,因为另一个也指向这个内存,自然就获取了变化后的值。而对于基本类型的变量,也就是我们大家所理解的,在复制后就开辟新的内存进行数据存储,所以两个变量互不干扰。

关于传参

JavaScript的参数传递都是按值传递

基本类型变量很好理解,但是对于引用类型的变量也许存在疑惑,不要紧,你只要理解下面这句话即可:

引用类型变量的传参是按值传递,但是访问引用变量的值时依然是按引用访问同一个对象。

下面举三个例子,对于引用类型,读者需理解透彻。

第一个例子是基本类型变量的传参,第二、三是引用类型变量的传参:

var name = "TabWeng";

function sayFunction(name){
name = "Hi,"+name;
console.log(name);
} sayFunction(name);
console.log(name);

运行结果:

Hi,TabWeng
TabWeng
var Person = new Object();
Person.name = "TabWeng"; function sayFunction(obj){
obj.name = "Hi," + obj.name;
console.log(obj.name);
} sayFunction(Person);
console.log(Person.name);

运行结果:

Hi,TabWeng
Hi,TabWeng

虽然是按值传递,但是在访问的时候是按引用访问同一个对象,所以Person.name也改变了。

var Person = new Object();
Person.name = "TabWeng"; function sayFunction(obj){
obj.name = "Hi," + obj.name;
console.log(obj.name);
obj = new Object();
obj.name = "My name is Tom, I am go to another memory";
console.log(obj.name);
} sayFunction(Person);
console.log(Person.name);

运行结果:

Hi,TabWeng
My name is Tom, I am go to another memory
Hi,TabWeng

这个例子说明了不是按引用传递,否则第三行的结果应该是My name is Tom, I am go to another memory

作用域

作用域链

作用域链很好理解,一句话概括变量在作用域中的访问权限:

外面不能访问里面,里面可以访问外面,在搜索变量时,从里向外搜索。

作用域链是在创建函数的时候产生的,在创建函数的时候,会创建它的执行环境和作用域链,一开始的时候,会创建一个包含全局环境(全局对象)的作用域链,然后把该函数的活动对象推入到作用域链的前端(也就是里面,最下面),如果函数里面还有函数,那么再依次推入,这样就形成一条作用域链。

假设作用域链(实际上是一张列表)里面有三个指针指向三个对象,列表最上面的指针指向全局对象(假设称为obj_1),中间的指针指向活动对象(假设称为obj_2),下面的指针指向最前端的活动对象(假设称为obj_3)。那么,当前的活动对象的变量是无法访问下面指针的活动对象的,即obj_2无法访问obj_3的变量,反之就可以。

延长作用域链

  • try catch
  • with

    以上两者可延长作用域链,把变量放在作用域前端(即当前环境)。

没有块级作用域

for(var i = 0; i < 3; i++){
console.log("in i: "+i);
} console.log("out i:"+i);

运行结果:

in i: 0
in i: 1
in i: 2
out i:3

这与其他高级语言不同。

参考

  • 《JavaScript高级程序设计》

JavaScript变量和作用域的更多相关文章

  1. javascript变量的作用域

    javascript变量的作用域 基本类型和引用类型 基本类型值指的是简单的数据段,而引用类型值指的是那个可能由多个值组成的对象  讲一个值赋值给变量时,javascript解析器首先要确定是基本类型 ...

  2. javascript 函数初探 (三)--- javascript 变量的作用域

    javascript 变量的作用域: 这是一个至关重要的问题.特别是当我们从别的语言转向javascript时,必须要明白一点,即在javascript中,变量的定义并不是以代码块作为作用域的,而是以 ...

  3. 深入理解 JavaScript 变量的作用域和作用域链

    一个变量的作用域(scope)是程序源代码中定义这个变量的区域.简单的说,作用域就是变量与函数的可访问范围.全局变量拥有全局作用域,在JavaScript代码中的任何地方都有定义.局部变量是在函数体内 ...

  4. JavaScript变量的作用域和函数的作用域的区别

    变量作用域和函数作用域都涉及到变量值的变化,本文旨在让大家明白他们之间的区别 变量的作用域: 变量的作用域无非就是两种:全局变量和局部变量. Javascript语言的特殊之处,就在于函数内部可以直接 ...

  5. JavaScript - 变量,作用域,内存

    JavaScript 变量可以用来保存两种类型的值:基本类型值和应用类型值.基本类型的值源自以下5种基本数据类型:Undefined.Null.Bollean.Number和String. 所有变量都 ...

  6. 深入浅出 JavaScript 变量、作用域和内存 v 0.5

    本文主要从原理入手分享变量和作用域的相关知识,最后结合本文所分享知识,再次深入了解下闭包的运行原理. 主要参考<JS高级程序设计> <JS权威指南> <高性能 JS> ...

  7. 【javascript 变量和作用域】

    今天学习了javascript 的变量和作用域的基本知识,对于以前在开发中遇到的一些不懂的小问题也有了系统的认识,收获还是比较多的. [基本类型和引用类型] ECMAScript 变量可能包含两种不同 ...

  8. [从jQuery看JavaScript]-变量与作用域链

    jQuery片段: var // Will speed up references to window, and allows munging its name. window = this, //  ...

  9. [label][JavaScript][The Defined Guide of JavaScript] 变量的作用域

    变量的作用域 一个变量的作用域(scope)是程序中定义这个变量的区域. 全局(global)变量的作用域(scope)是全局性的,即在JavaScript代码中,它处处都有定义.    而在函数之内 ...

随机推荐

  1. MySQL查询优化之explain的深入解析

    在分析查询性能时,考虑EXPLAIN关键字同样很管用.EXPLAIN关键字一般放在SELECT查询语句的前面,用于描述MySQL如何执行查询操作.以及MySQL成功返回结果集需要执行的行数.expla ...

  2. 记录-div绝对定位针对手机浏览器的区别

    最近搞个wap ,有一个需求就是一些文字描述定位到一张图片上的某个地方,按照以往的方式直接通过定位div position: absolute; PC chrome 模拟手机显示没问题! 但是,在ip ...

  3. 表设置了自增后往里面插入不自增的id时的处理方法

    SET IDENTITY_INSERT 表名 ON 中间写insert语句,但是这里必须把列名更上 SET IDENTITY_INSERT 表名 OFF

  4. Mac Pro 编译安装 Redis-3.2.3

    Redis官方下载地址:http://redis.io/download Redis安装 cd /usr/local/src/redis-3.2.3 sudo make sudo make insta ...

  5. 【Android学习】解决Eclipse AVD打开慢的问题

    1.创建的时候勾选“Snapshot” 2.之后Start时候勾选对应的.

  6. MyEclispe发布web项目-遁地龙卷风

    (-1)写在前面 我用的是MyEclipse8.5. 还记得以前帮助一个女同学解决问题的时候,特意情调了要先启动服务在发布项目,其实单独的时候都是知道的,总和起来后就容易片面的给出结论.因为不会发生问 ...

  7. 按Enter键执行表单验证

    document.onkeydown = function(evt){ var evt = window.event?window.event:evt; if (evt.keyCode==13) { ...

  8. python用二进制读取文件

    python二进制读取文件 很多时候,都需要用到二进制读取文件.毕竟很多信息不是以文本的形式存储.例如:图片,音乐等等.这些东西都是有规则的二进制文件. 在python中,二进制读取采用rb的方式. ...

  9. 简单介绍一下python Queue中常用的方法

    Queue.qsize() 返回队列的大小 Queue.empty() 如果队列为空,返回True,反之False Queue.full() 如果队列满了,返回True,反之FalseQueue.fu ...

  10. xampp本地配置多域名

    xampp内建apache服务器,也是可以配置vhosts的 1. 打开httpd.conf文件,搜索vhosts 发现这句话: # Virtual hosts Include conf/extra/ ...