JS从入门到摒弃-基础范例和援用范例
JS有number,string,null,undefined,boolean,array,object七种数据范例,而JS的变量,依据指向数据范例的差别,也分为两种范例,一种基础范例,一种援用范例.
1. 基础范例
基础范例包含: number, string, null, undefined, boolean这五种.凡是变量指向这五种数据范例的都称之为基础范例.
var test1 = 'hahaha'; // string
var test2 = 1; // number
var test3 = true; // boolean
假设有以上变量,那末他们在内存中栈区的存储构造大概是这模样的.
栈区指针 | 栈区值 |
test1 | hahaha |
test2 | 1 |
test3 | true |
var test = '321';
var test = '123';
var test1 = test;
console.log(test === test1); // true
实行以上语句以后,你可能会以为变量test
的值从字符串'321'
变成了字符串'123'
.并非值转变了,而是test
只是一个指针,上面的两条语句都只是在为同一个指针指向差别的值罢了.值是不可被转变的.实行第三条语句的时刻,起首初始化一个test1
变量,然后把test
的变量赋值给test1
.这类赋值称为深拷贝.如图:
指针 | 值 |
test | ‘123’ |
test1 | ‘123’ |
末了一条语句之间的比较实际上是test
和test1
之间的值作比较.也就是console.log('123' === '123')
,之所以节外生枝的诠释末了两条语句,缘由是由于援用范例的赋值和比较并非云云.
2. 援用范例
援用范例包含: object和array这两种.凡是变量指向这两种数据范例的都称之为援用范例.
var china = {
tianjin: '天津',
beijing: '北京'
};
var huabei = {
tianjin: '天津',
beijing: '北京'
};
假设有以上变量,那末他们在内存中栈区和堆区的存储构造大概是这模样的.
栈区指针 | 栈区值 |
china | china对象在堆区的内存地点 |
huabei | huabei对象在堆区的内存地点 |
堆区地点 | 堆区值 |
china对象在堆区的内存地点 | china对象 |
huabei对象在堆区的内存地点 | huabei对象 |
china.handan = '邯郸';
console.log(china.handan); // '邯郸'
当我们继承实行上面语句的时刻china堆区值内部的属性除了原有的tianjin
和beijing
以外又动态的添加了一个handan
属性.这说明援用范例的值是能够被转变的.
console.log(china === huabei); // false
china对象和huabei对象内的属性明显一样,然则完整相称比较符却返回了false.这进一步证明了援用范例的比较是比较二者在堆区的地点是不是雷同.假如我们对两个对象的内部的属性举行比较呢.
console.log(china.tianjin === huabei.tianjin) // true
这里又会返回true,这是由于我们做比较的对象的属性是基础范例.他们会比较内部的值,而不是比较二者在堆区内的地点.
末了说一下援用范例的赋值.继承上面的代码
var asia = china;
asia.tianjin = '红桥';
console.log(asia.tianjin); // 红桥
console.log(china.tianjin); // 红桥
实行上面语句你会发明明显转变的是asia的属性,然则china的属性也随着转变了.这是由于赋给asia的值是china对象在堆区的内存地点,而不是china对象自身.二者实际上指向同一个堆区对象.也因而,转变个中任何一个的属性,别的一个也会随之变动.这类赋值也称之为浅拷贝.
栈区指针 | 栈区值 |
china | china对象在堆区的内存地点 |
asia | china对象在堆区的内存地点 |
堆区地点 | 堆区值 |
china对象在堆区的内存地点 | china对象 |
总结
基础范例:值不可变,存放于栈区,互相比较是基于值举行比较,互相赋值是深拷贝赋值.
援用范例:值可转变,同时存放于栈区和堆区,互相比较是基于在堆区内的地点,互相赋值是浅拷贝.