资讯专栏INFORMATION COLUMN

变量的值

noONE / 2689人阅读

摘要:在将一个值赋值给变量时,解析器会确定值的类型。添加属性变量的值是复杂数据类型时,可以简单的为其添加属性。赋值变量的值从一个变量向另一个变量复制值时,会为新的变量分配位置,然后把变量的值复制到该位置上。

ECMAScript 的变量是松散类型的,也就是说可以保存任何类型的数据。数据的类型分为简单数据类型和复杂数据类型。简单数据类型有: Undefined、Null、Boolean、Number和 String;复杂数据类型只有一种,就是Object。在将一个值赋值给变量时,解析器会确定值的类型。如果是简单类型,直接保存在变量中,如果是复杂类型,则把值保存在内存中,而把值的引用保存在变量中。也就是说变量的值有两种:简单的数据类型的值或者复杂数据类型的引用。因此,在操作变量时,就会有所不同。

1、添加属性

变量的值是复杂数据类型时,可以简单的为其添加属性。这个很容易理解,而当变量的值是某些简单的数据类型时,为其添加属性也不会报错,但之后却不能访问,如下:

 
var person= "xiaoming";
name.age = 27;
alert(name.age); //undefined

这是因为JavaScript引擎在处理添加属性的代码时,会在内部临时创建一个对应包装类型(这里是String类型)的临时对象, 并把对基本类型的操作代理到对这个临时对象身上,但在操作完成之后,临时对象就扔掉了,下次访问时,重新建立新的临时对象,添加的属性并不会 保存。有时,在代码中直接调用基本数据类型的方法的方法也是同样的道理。因此,只能给复杂数据类型的值添加属性。

2、赋值变量的值

从一个变量向另一个变量复制值时,会为新的变量分配位置,然后把变量的值复制到该位置上。不管变量的中保存的是基本数据类型的值,还是复杂数据类型的引用,都是直接把变量中保存的值直接赋值并保存到新的位置上面。

简单的数据类型很好理解,复杂的数据类型可以参照下图:

变量obj2复制的是obj1中保存的对象的引用,复制之后,obj1和obj2中分别保存一个指向该对象的引用。

3、传递参数

ECMAScript 中所有函数的参数都是按值传递的。也就是说在传递参数时,实际上就是把变量中保存的值复制了一遍,保存在对应的参数中,从而变成了函数内部的一个变量。这时,需要注意的一点时,对于简单的数据类型,新的变量(参数)和外部的变量已经没有联系了。而对于复杂数据类型,因为两个变量中保存的都是对象的引用,因此两个变量还是仅仅联系在一起的,如下:

var a = 3;
var o = { name:"xiaoming" };
function fn(obj, num){
     num += 10;
     o.name = "hh";
     return num;
}
var res = fn();

alert(res);     //13
alert(a);     //3
alert(o.name); //"hh"

4、检测类型

正如开头说的变量是松散的,为了确保代码可以正确的执行,很多时候都需要检测变量值的类型。变量的值是简单的数据类型时(null除外),只需要使用typeof操作符,就可以很简单的检测出来。但变量的值是复杂数据类型的引用时,就有点麻烦了,使用typeof始终只会返回‘object’。如果知识简单的检测,可以使用 instanceof 操作符。使用如下:

res = obj instanceof constructor

只要变量是给定复杂数据类型的实例,那么instanceof 操作符就会返回 true。需要说的一点是, 所有复杂数据类型的值都是 Object 的实例,使用这个操作符检测是不是Object构造函数的实例时,都会返回true。

使用这种方式检测在大多数情况下都是没有问题的,但当页面的中存在嵌套的框架或者在一些特殊的浏览器中就会出现问题。例如,在一个frame中定义了一个数组arr,而在最外层的window环境中检测,就会返回false。为了确保检测结果的正确,可以使用Object原声的toString方法,对于任何的复杂数据类型,这个方法都会返回“ [object NativeConstructorName]”格式的字符串,例如:

Object.prototype.toString.call([])          //"[object Array]"

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/82093.html

相关文章

  • 变量和作用域

    摘要:当代码在一个环境中执行时,会创建变量对象的一个作用域链,作用域链的用途,是保证对执行环境有权访问的所有变量和函数的有序访问。作用域链的下一个变量对象则来自下一个包含环境。 前言 JavaScript中变量是松散类型,这样它只在特定的时间内用于保存一个特定的值。由于不存在定义某个变量必须要保存何种数据类型的规则,变量的值和其数据类型可以在脚本的生命周期内改变。 1. 基本类型和引用类型的...

    Codeing_ls 评论0 收藏0
  • Java中的Volatile关键字

    摘要:变量可见性问题的关键字保证了多个线程对变量值变化的可见性。只要一个线程需要首先读取一个变量的值,基于这个值生成一个新值,则一个关键字不足以保证正确的可见性。 Java的volatile关键字用于标记一个Java变量为在主存中存储。更确切的说,对volatile变量的读取会从计算机的主存中读取,而不是从CPU缓存中读取,对volatile变量的写入会写入到主存中,而不只是写入到CPU缓存...

    JohnLui 评论0 收藏0
  • 值类型、执行环境和垃圾回收

    摘要:中的变量是松散类型的即它在不同的时期可以有不同类型的值这也是最强大的的特性之一基本类型和引用类型的值的值类型有两种基本类型引用类型。 ECMAscript中的变量是松散类型的,即它在不同的时期可以有不同类型的值,这也是ECMAscript最强大的的特性之一. 基本类型和引用类型的值 javascript的值类型有两种:基本类型 引用类型。基本类型的值是指的简单的数据段,基本类型有五种,...

    darkbaby123 评论0 收藏0
  • Java并发编程之原子性操作

    摘要:将与当前线程建立一对一关系的值移除。为了让方法里的操作具有原子性,也就是在一个线程执行这一系列操作的同时禁止其他线程执行这些操作,提出了锁的概念。 上头一直在说以线程为基础的并发编程的好处了,什么提高处理器利用率啦,简化编程模型啦。但是砖家们还是认为并发编程是程序开发中最不可捉摸、最诡异、最扯犊子、最麻烦、最恶心、最心烦、最容易出错、最不符合社会主义核心价值观的一个部分~ 造成这么多最...

    instein 评论0 收藏0
  • JavaScript学习笔记 - 变量、作用域与内存问题

    摘要:语句中的块语句对来说,将会指定对象添加到作用域链中。在严格模式下,初始化未经声明的变量会导致错误。查询标识符搜索过程从作用域链的前端开始,向上逐级查询与给定名字匹配的标识符。 本文记录了我在学习前端上的笔记,方便以后的复习和巩固。 4.1基本类型和引用类型的值 ECMAScript变量可能包含两种不同数据类型的值:基本类型值和引用类型值。基本类型指的是简单的数据段,而引用类型值指那些可...

    lavnFan 评论0 收藏0

发表评论

0条评论

noONE

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<