1、基本类型基本的数据类型有:undefined,boolean,number,string,null.基本类型的访问是按值访问的,就是说你可以操作保存在变量中的实际的值。 [h2]1).基本类型的值是不可变得:[/h2]任何方法都无法改变一个基本类型的值,比如一个字符串:
- name.toUpperCase(); // 输出 'JOZO'
复制代码- console.log(name); // 输出 'jozo'
复制代码 会发现原始的name并未发生改变,而是调用了toUpperCase()方法后返回的是一个新的字符串。再来看个:
- person.method = function(){//...};
复制代码- console.log(person.age); // undefined
复制代码- console.log(person.method); // undefined
复制代码 通过上面代码可知,我们不能给基本类型添加属性和方法,再次说明基本类型是不可变得;
[h2]2).基本类型的比较是值的比较[/h2]只有在它们的值相等的时候它们才相等。但你可能会这样:
- console.log(a == b);//true
复制代码 它们不是相等吗?其实这是类型转换和 == 运算符的知识了,也就是说在用==比较两个不同类型的变量时会进行一些类型转换。像上面的比较先会把true转换为数字1再和数字1进行比较,结果就是true了。这是当比较的两个值的类型不同的时候==运算符会进行类型转换,但是当两个值的类型相同的时候,
即使是==也相当于是===。
- console.log(a === b);//true
复制代码 [h2]基本数据类型是存放在栈区的[/h2]假如有以下几个基本类型的变量:
var name = "jozo";
var city = "guangzhou";
var age = 22;
[h1]2.引用类型[/h1]引用类型会比较好玩有趣一些。除了上面的一些类型之外都是引用类型了,也可以说就是对象了,对象是属性和方法的集合
也就是说引用类型可以拥有属性和方法,属性又可以包含基本类型和引用类型。来看看引用类型的一些特性:
[h2]1).引用类型的值是可变的[/h2]- 我们可以为引用类型添加属性和方法,也可以删除其属性和方法,如:
复制代码
- var person = {};//创建空对象 --引用类型
复制代码- person.sayName = function(){console.log(person.name);}
复制代码- person.sayName();// 'jozo'
复制代码
- delete person.name; //删除person对象的name属性
复制代码- person.sayName(); // undefined
复制代码 上面代码说明引用类型可以拥有属性和方法,并且是可以动态改变的。
[h2]2.1引用类型的值是同时保存在栈内存和堆内存中的对象[/h2]javascript和其他语言不同,其不允许直接访问内存中的位置,也就是说不能直接操作对象的内存空间,那我们操作啥呢?实际上,是操作对象的引用,
所以引用类型的值是按引用访问的。准确地说,引用类型的存储需要内存的栈区和堆区(堆区是指内存里的堆内存)共同完成,栈区内存保存变量标识符和指向堆内存中该对象的指针,
也可以说是该对象在堆内存的地址。假如有以下几个对象:
- var person1 = {name:'jozo'};
复制代码- var person2 = {name:'xiaom'};
复制代码- var person3 = {name:'xiaoq'};
复制代码 [h2]2.2 引用类型的比较是引用的比较[/h2]- console.log(person1 == person2); // true
复制代码 [h2]2.3 简单赋值[/h2]- 在从一个变量向另一个变量赋值基本类型时,会在该变量上创建一个新值,然后再把该值复制到为新变量分配的位置上:
复制代码
此时,a中保存的值为 10 ,当使用 a 来初始化 b 时,b 中保存的值也为10,但b中的10与a中的是完全独立的,该值只是a中的值的一个副本,此后,
这两个变量可以参加任何操作而相互不受影响。
[h2]2.4 对象引用[/h2]当从一个变量向另一个变量赋值引用类型的值时,同样也会将存储在变量中的对象的值复制一份放到为新变量分配的空间中。前面讲引用类型的时候提到,
保存在变量中的是对象在堆内存中的地址,所以,与简单赋值不同,这个值的副本实际上是一个指针,而这个指针指向存储在堆内存的一个对象。那么赋值操作后,
两个变量都保存了同一个对象地址,则这两个变量指向了同一个对象。因此,改变其中任何一个变量,都会相互影响:
- var a = {}; // a保存了一个空对象的实例
复制代码- var b = a; // a和b都指向了这个空对象
复制代码
- console.log(a.name); // 'jozo'
复制代码- console.log(b.name); // 'jozo'
复制代码
- console.log(a == b);// true
复制代码 [h1]3 基本包装类型(包装对象):[/h1]先看下以下代码:
上面我们说到字符串是基本数据类型,不应该有方法,那为什么这里s1可以调用substr()呢?
通过翻阅js权威指南第3.6章节和高级程序设计第5.6章节我们得知,ECMAScript还提供了三个特殊的引用类型Boolean,String,Number.我们称这三个特殊的引用类型为基本包装类型,也叫包装对象.
也就是说当读取string,boolean和number这三个基本数据类型的时候,后台就会创建一个对应的基本包装类型对象,从而让我们能够调用一些方法来操作这些数据.
所以当第二行代码访问s1的时候,后台会自动完成下列操作:
- 创建String类型的一个实例;// var s1 = new String("helloworld");
复制代码
- 在实例上调用指定方法;// var s2 = s1.substr(4);
复制代码
正因为有第三步这个销毁的动作,所以你应该能够明白为什么基本数据类型不可以添加属性和方法,这也正是基本装包类型和引用类型主要区别:对象的生存期.使用new操作符创建的引用类型的实例,在执行流离开当前作用域之前都是一直保存在内存中.而自动创建的基本包装类型的对象,则只存在于一行代码的执行瞬间,然后立即被销毁
|
|