从头开始学JavaScript (八)——变量

时间:2022-05-10 16:06:52

原文:从头开始学JavaScript (八)——变量

从头开始学JavaScript (八)——变量

一、变量分类:

基本类型值:null、undefined、number、string、Boolean;

引用类型值:保存在内存中的对象,如:Object / Array / Function / Date / RegExp / Error / Map / Set …

二、属性

二者的定义方式是类似的:创建一个变量并为其赋值。

2.1基本类型值不能添加删除属性

2.2引用类型的属性可以动态添加删除属性

例如:

 <script type="text/javascript">
var person = new Object();
person.name = "Nicholas";
alert(person.name); //"Nicholas"
</script>

上述例子创建了一个对象并将其保存在变量person中,然后我们又为这个对象添加了一个name属性,并将一个字符串赋值给该属性。

再看一个例子:

  <script type="text/javascript">
var name = "Nicholas";
name.age = 27;
alert(name.age); //undefined
</script>

可见基本类型的值是不能动态添加属性的,尽管不报错。

三、复制变量值

3.1基本类型值复制变量

同样通过代码来说明:

var num1=2;
var num2=num1;

变量num2只是把num1中存储的值(2)复制了一份,然后保存在自己的内存空间,此后这两个变量可以参与任何操作而互不影响。

3.2引用类型值复制变量

 var obj1= new Object();
var obj2=obj1;
obj1.name="jack";
alert(obj2.name);//jack

同样的,obj2也是把obj1中存储的值复制了一份,然后保存在自己的内存空间,只不过这个值实际上是一个指针,而这个指针指向存储在堆中的一个对象。复制操作结束后,两个变量实际上将引用同一个对象。两个变量其实是相互同步的。

四、传递参数

ECMAscript中所有函数的参数都是按值传递的:把函数外部的值复制给函数内部的参数,就和把值从一个变量复制到另一个变量一样。

4.1基本类型的值

被传递的值会被复制给一个局部变量(也就是命名参数:形参,也就是arguments对象中的一个元素)。见http://www.cnblogs.com/yxField/p/4224380.html中所提到的。

需要说明的是:String一个特殊的基本数据类型

在很多语言中,String是以对象的形式表示的,但在ECMAScript里没有沿用这种传统,String是当作一种基本数据类型,但它是一个比较特殊的基本类型。

看上去好像String应该做为一个引用类型,可实际上它不是,因为它不是对象。那么看起来它应该是基本数据类型,应该是通值传递的方式来操作。

看下面例子:

var stra = "这是一个字符串";
var strb = stra;
stra = "这是另外一个字符串";
console.log(strb); // 这是一个字符串

上面例子我们看到,仿佛stra通过值传递的方式复制了一份给了strb。当stra改变的时候,strb并没有改变,似乎我们已经可以下结论,String就是个基本数据类型。

可是,因为String是可以任意长度的,通过值传递,一个一个的复制字节显示效率依然很低,看起来String也可以当作引用类型。

看下面例子:

var a = "myobject";
a.name = "myname";
console.log(a.name); // undefined

显示String无法当作一个对象来处理。实际上,javascript里的String是不可以改变的,javascript也没有提供任何一个改变字符串的方法和语法。

var a = "myobject";
a = a.substring(3,5)
console.log(a); // bj

记住这样做,就没有改变String字符串"myobject",只a引用了另一个字符串"bj","myobject"被回收了。

所以可以这样讲,String实际上并不符合上面两种数据类型分类。它是具有两方面属性介于两都之间的一种特殊类型。

4.2引用类型的值

在向参数传递引用类型的值时,会把这个值在内存中的地址复制给一个局部变量,因此这个局部变量的变化会反应在函数的外部。

例如:

 <script type="text/javascript">
function setName(obj) {
obj.name = "Nicholas";
} var person = new Object();
setName(person);
alert(person.name); //"Nicholas" </script>

上述例子中,变量person在复制给obj时,把它所保存的对象在内存中的地址复制给了obj,所以obj和person引用的还是同一个对象。

为了证明对象是按值传递的,再看个例子:

  function setName(obj) {
obj.name = "Nicholas";
obj=new Object();
obj.name="jack";
} var person = new Object();
setName(person);
alert(person.name); //"Nicholas"

上述例子中,如果person是按引用传递的,那么person.name就会变成Jack,这说明即使在函数内部修改了参数的值,但是原始的引用仍然保持不变。实际上,当函数内部重新写obj时,这个变量引用的就是一个局部对象了,这个局部对象会在函数执行完之后被立即销毁。

五、检测类型

5.1检测基本数据类型:typeof

见http://www.cnblogs.com/yxField/p/4211704.html

5.2检测引用类型值:instanceof

例如:

         var s =[1,2];
var a = true;
var i = new Object(); alert(i instanceof Object); //true
alert(a instanceof Object); //false
alert(s instanceof Array); //true