(深夜课堂)Javascript 变量、作用域和内存问题(1)

JavaScript变量松散类型的本质,决定了它只是在特定时间保存特定值的一个名字而已。

ECMAScript变量可能包含两种不同数据类型的值:基本类型值,引用类型值。
在将一个值附值给变量时,解析器必须确定这个值到底是基本类型还是引用类型。基本数据类型例如:Undefined Null Boolean Number String,它们都是按值访问的,可以操作保存在变量中的实际值。
引用类型的值是保存在内存中的,与其他语言不同,ECMAScript不允许直接访问内存中的位置,也就是说,不能直接操作对象的内存空间。在操作对象的时候,实际是在操作对象的引用。补充:当复制保存着对象的某个变量时,操做的是这个对象的引用;但是当为该对象添加属性的时候,操作的就是实际的对象了。

动态属性:
定义基本类型和引用类型的方法是类似的:创建一个变量,并且为它赋值。但是,它们其实是很有区别的。例如,引用类型可以添加并修改属性和方法:

var person = new Object(); 
person.name = "Nicholas"; 
alert(person.name); //"Nicholas"

但是对于一个基本类型,这就没戏的:

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

看到了?根本存不住啊。。。

复制变量:
基本类型的复制是值传递,两个变量做了相等的赋值后,互相不影响。
但是引用类型的复制则是地址传递,相当于是两个“指针”指向了同一个内存,所以对一个变量赋值,另一个也会被改变。
栗子:

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

传递参数:
ECMAScript中,所有函数的参数都是按值传递的。
当参数是基本类型的值的时候:传递的值会被复制给一个局部变量;当参数是引用类型的时候,则会把这个值在内存中的地址复制给一个局部变量。
请看下面这两个例子:

function addTen(num) {
    num += 10;
    return num; 
}

var count = 20;
var result = addTen(count); 
alert(count); //20 不变  
alert(result); //30
function setName(obj) {
    obj.name = "Nicholas";
}
var person = new Object();
setName(person);
alert(person.name);    //"Nicholas"

第二个栗子不太好理解,有很多人会认为这恰恰说明了参数是地址传递的。让我们来分析一下:
首先,代码创建了一个object对象,将其保存在了变量person中,然后,这个变量作为参数,复制给了obj。此时,在函数内部,obj和person引用的是同一个对象,也就是说,参数是按照值传递的,但是obj是按引用来访问的person对象。于是,当我们给obj添加新的属性的时候,person对象也会有反应,因为person指向的对象在堆栈中只有一个。
让我们再来看下面这个修改过的栗子,来证明参数传递确实是值传递:

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

如果参数是地址传递,那么最后一行代码的显示值应该是Greg。这说明了, 在函数内部修改了参数的值,但是原引用依旧保持不变,是真正的值传递喔~

检测类型:
检测基本数据类型时,使用typeof函数

var s = "Nicholas";
var b = true;
var i = 22;
var u;
var n = null;
var o = new Object();
alert(typeof s);//string
alert(typeof i);//number
alert(typeof b);//boolean
alert(typeof u);//undefined
alert(typeof n);//object 很神奇
alert(typeof o);//object

检测引用对象的值,使用instanceof,因为引用对象使用typeof方法,都会返回object,而我们想知道的也许是,它到底是什么类型的对象:
结果会返回true/false

alert(person instanceof Object); //person是不是Object类型的对象?  
alert(colors instanceof Array); //colors是不是Array类型的对象?   
alert(pattern instanceof RegExp); //pattern是不是RegExp类型的对象?
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值