关於Javascript基本类型和引用类型小知识

ECMAScirpt 变量有两种不一样的数据类型:基本类型引用类型javascript

基本的数据类型有:undefinedbooleannumberstringnull. 基本类型的访问是按值访问的,就是说你能够操做保存在变量中的实际的值。JavaScript中除了上面的基本类型以外就是引用类型了。java

区别以下:
基本类型:segmentfault

  • 佔用空间固定,保存在栈中
  • 保存与复製的是自己
  • 使用typeof检测数据类型
  • 值类型

引用类型:函数

基本类型是不会改变,衹能从新赋值,而引用类型值是能够改变的指针

var a = '123456789',
      b = a;
 
a = '321';
console.log(a) // 321
console.log(b) // 123456789

上面因為是把值保存在了变量了 而不是保存的是引用地址,因此他们两个是相对独立的总体,互不影响。可是若是换成引用类型的话code

var a = {
    n: '123456789'
},
b = a;

a.n ='321';
console.log(a) // { n: '321' }
console.log(b) // { n: '321' }

缘由在於在javascript语言中建立的对象值中其保存的是对象的引用(也就是一个地址.引用类型值保存在内存中,而JS是不能直接访问内存的,因此对於引用类型,操做的不是实际的对象而是对象的引用。)对象

这里有个小提示説一下,假如两个相同的基本类型或引用类型(内容同样)相比,看看结果是怎样的?ip

var base1 = '123',
    base2 = '123',
    obj1 = { a: '123' },
    obj2 = { a: '123' };

console.log(base1 === base2) // true
console.log(obj1 === obj2) // false

若是你还错了那就证实你没理解透上面的东西了,由于前面是值之间直接比较,后面是指向地址的比较,即便两个引用类型看起来同样,衹要不是同一个声明变量,它们就必定不一样。内存

知识一:基本类型值就是简单的数据段;引用类型值保存的是对象的引用,不是实际的对象。

可是在函数中的对象传值又是否是同一回事呢?看看下面代码ci

function setName(obj) {
    obj.name = '1';
    obj = {};
    obj.name = '2';
}

var obj = {};
setName(obj);

console.log('最终结果obj:', obj) // 最终结果obj: { name: '1' }

没错,结果出乎意料的是1.而不是大多数人刚开始认为的2.
接下来咱们在一步步分析出在函数过程当中对象发生了什么样的变化?稍微修改下对象名便於区分。

function setName(innerObj) {
    console.log('初始的innerObj:', innerObj); // 初始的innerObj: {}

    innerObj.name = '1';
    console.log('第一次设置属性值的innerObj:', innerObj); // 第一次设置属性值的innerObj: { name: '1' }

    //保存下原对象
    var _innerObj = innerObj;

    innerObj = {};
    console.log('从新赋值的innerObj:', innerObj); // 从新赋值的innerObj: {}

    innerObj.name = '2';
    console.log('第二次设置属性值的innerObj:', innerObj); // 第二次设置属性值的innerObj: { name: '2' }

    console.log('二者之间是否是同一个对象?:', _innerObj == innerObj) // 二者之间是否是同一个对象?: false
    console.log('innerObj:', innerObj) // innerObj: { name: '2' }
    console.log('_innerObj: ', _innerObj) // _innerObj:  { name: '1' }
}

var outerObj = {};
setName(outerObj);
console.log('最终结果outerObj:', outerObj) // 最终结果outerObj: { name: '1' }

过程当中能够看出在函数中间 innerObj = {} 以后;对象的指向就已经变了,也就是说这里至关於从新创建一个新的指向,后续的操做都是基於新指向之上进行的。
此时,outerObj === _innerObj !== innerObj, 因此最终输出的是1而不是2.

若是还有些混乱的同窗,看看若是不经过函数直接修改会是什么结果?

var obj = {'a':1}
obj = {};
obj = {'a':2};
console.log(obj) // { a: 2 }

此次确确实实的是输出2了。

知识二:JS中全部函数传参都是按值传递的。
相关文章
相关标签/搜索