n这是个麻烦的话题,文字很不好组织,不知道我是否能组织好语言
固有对象 :
未定义 空值 布尔值 字符串 数值 通用对象 数组 函数 等都是(其他一些和我们的话题有些远,就不说了)
未定义 和 空值 的不同:
- 未定义 是个值,是个关键字,表示一个对象没有值
- 空值 是个值,是个关键字,它的值就是 空 null,表示一个对象的值是null
这个说法可能不够标准不过:
typeof undefined;//undefined typeof null;//object
JavaScript是面向对象的,所有的值都应该有一个类型,可是唯独undefined是个特殊的.undefined是关键字
null是值,也是对象,也是关键字.理由是:
Function=5;//可以这样 null=6;//不行,这就是为什么说null是关键字了,一个特殊的对象,undefined也有这个特性
也就是说,Function,Array,Object都是一个函数对象,可以改变,undefined,null是关键字,不能改变.
非固有对象 :
由固有对象构造出的对象就是非固有对象.我们还是简称对象更容易描述些.对象都有值,也许值是null或者undefined.
var str='string';//等同 var str=new String('string');//等同 var str=String('string');
===ps ===
今天看了一篇文章才发现,上面有不同的,
var str='sssss'; typeof str=='string'; var str= new String('ffff'); typeof str=='object';
===ps end===
这三句都做了同样的事情.可以这样描述:
- 创建了一个对象,他的名字是:str
- 创建了一个字符串型的对象,他没有名字(匿名 ),他的值是:string
- 令str指向这个匿名 对象:str 的类型和值也就同这个匿名 对象一样了
当然JavaScript引擎是否优化这个实现,使得这个说法站不住脚,已经不重要了.概念是这样的.
var obj={str:5,o:{v:'dfd'}};
用同样的描述方法我们来说说:
- 创建了一个对象,他的名字是:obj
- 创建了一个匿名对象
{str:5,o:{v:'dfd'}}
- 令obj指向这个匿名 对象:obj 的类型和值也就同这个匿名 对象一样了
请使用FireFox+FireBUG来测试.console是FireBUG的调试API
var obj1={n:5,o:{v:'obj1v'}}; var obj2=obj1; obj2=3; console.dir(obj1);//obj1没有改变 obj2={}; console.dir(obj1);//obj1没有改变 obj2=obj1; obj2.o={v:'obj2v'}; console.dir(obj1);//obj1改变了
第1次,obj1没有改变,是因为
obj2=3;
重新创建了一个匿名对象3,改变了obj2的指向
第2次的情况和第1次一样.
第3次
- 创建了一个匿名对象
{v:'obj2v'}
- 令obj2.o指向这个匿名对象的值
那为什么obj1.o也变了?让我们再看看
var obj2=obj1;
在JavaScript里由于obj1是一个非值型 对象这样的赋值是引用,对于引用 变量obj2,所有对obj2的成员操作 都会施加到obj1的成员上.
var obj3='string'; obj1=obj3;
向这样的操作,对于obj1来说不是成员操作,所有obj2不会改变.
再回头看看上面的描述,和关于类型 中的
无法对 值类型赋予新的可变成员
是对应的,因为你无法对 值类型赋予新的可变成员 ,自然就不会有成员操作 (当然指的是新成员,这话还不够严谨,prototype过来的算不算),因此说:(注意前提,不讲prototype的情况)
不存在值类型成员操作,只存在非值型成员操作,成员操作具有传染性
var o1={v:'dfd'}; var obj={str:5,o:o1};//obj.o引用o1 var o2=obj;//o2引用obj, o2.o={};//成员操作 console.dir(obj);//传染了,obj.o改变 console.dir(o1);//o1不是obj的成员,不变 var obj1={str:5,o:o1};//obj1.o引用o1 var o3=obj1; o2.o.v='aaa';//v可就是实实在在的{v:'dfd'}中的v呀 console.dir(o1);//o1变了
o1不是obj的成员?当然,o1和obj.o只不过都指向{v:'dfd'}罢了.再举个例子
var o={}; o.f=function(){return 1;}; var oo=o; oo.f=function(){return 2;};//仍然是成员操作,传染 o.f();//2
其实如果你学习过c/c++了解指针操作的话,我这个解释根本是多余的