值类型(基本类型):String,Number,Boolean,Null,Undefined。
引用类型:Array、Object、Function、Date等有多个值构成的可变长度的复杂类型。javascript
(1)基本类型的变量保存的是变量值,引用类型的变量保存的是内存地址;
(2)基本类型长度固定,在内存中占据固定大小的空间,数据存放在栈内存中;引用类型能够给对象添加属性和方法,长度不固定,数据存放在堆内存中。引用类型的存储须要栈区和堆区(堆区是指内存里的堆内存)共同完成,栈区内存保存变量标识符和指向堆内存中该对象的指针,也能够说是该对象在堆内存的地址;
(3)基本类型在赋值的时候拷贝值,引用类型在赋值的时候只拷贝地址,不拷贝值。html
const num1 = 5; const num2 = num1;
const obj1 = {}; const obj2 = obj1;
// 测试引用类型传值和数组类型传值 const obj = { success: false, result: { name: '222' } }; let name = obj && obj.result && obj.result.name; // name为一个str,具体的值为基础类型,name这里保存的是变量值,而不是引用地址 console.log(name); // 222 name = "333"; console.log(obj.result.name); // 222, name为变量值,name的改变并不会影响到obj.result.name obj.result.name = "44444"; console.log(obj.result.name); // 44444 console.log(name); // 333,name为变量值,而非引用地址,与obj.result.name相互不影响,所以obj.result.name的改变也不会引发name的变化
const obj = { success: false, result: { name: '222' } }; let result = obj && obj.result; console.log(result); // { name: '222' },obj.result是一个Object类型,这里result存的是obj.result的引用地址,result和obj.result指向堆中的同一个地址,相互影响 obj.result.name = "44444"; console.log(obj.result.name); // '44444' console.log(result); // { name: '44444' } result.name = "xxxxx"; // 属性修改,相互影响 console.log(obj.result); // { name: 'xxxxx' } // result从新赋值,指向一个新的引用地址,此时result与obj.result指向不一样地址,再也不相互影响 result = { name: 'ooooo' }; console.log(result); // { name: 'ooooo' } console.log(obj.result); // { name: 'xxxxx' }
const obj = { success: false, result: [0, 1] }; let result = obj && obj.result; console.log(result); //[0, 1],obj.result为Array类型,result和obj.result指向堆中的同一个地址,相互影响 console.log(obj.result); // [0, 1] result.push('aa'); // 数组的push操做是在原数组基础上操做,并不生成一个新的数组,result和obj.result依然指向同一个地址,相互影响 console.log(result); // [0, 1, 'aa'] console.log(obj.result); // [0, 1, 'aa'] result = [0, 1, 2]; // result从新赋值,此时result指向堆中一个新的地址,result与obj.result指向不一样地址,再也不相互影响 console.log(obj.result); // [0, 1, 'aa'] console.log(result); // [0, 1, 2]
基本类型参数的传递与基本类型的复制同样,传递的是变量值。java
function addTen(num) { num = num + 10; return num; } var count = 20; var result = addTen(count); console.log(count); // 20 console.log(result); // 30
引用类型参数的传递与引用类型的复制同样,传递的是内存地址。数组
function setName(obj){ obj.name = 'xxx'; obj = {name: 'ppp'}; // obj指向一个新的地址,与person再也不指向同一个地址 console.log(obj.name); // 'ppp' } const person = {name : 'oo'}; setName(person); console.log(person.name); // ‘xxx’
ECMAScript中全部函数的参数都是按值传递的。函数
也就是说,把函数外部的值复制给函数内部的参数,就和把值从一个变量复制到另外一个变量同样。基本类型的传递如同基本类型的复制同样,而引用类型值的传递,如同引用类型变量的复制同样。总结工具
很简单,javascript函数参数都是按值传递(都是栈内数据的拷贝)。
基本类型传的是值自己(由于直接把值存在栈内),引用类型传的是对象在内存里面的地址 (由于复杂对象存在堆内,因此在栈里存对象所在的堆地址)。
typeof是检测基本数据类型的最佳工具,可是对检测引用类型,返回的都是object,并不能肯定是哪一种类型的对象,没有意义。测试
基本类型:基本类型中的null,返回为object,其余的都能正常检测出准确的类型。 typeof('aa'); // 'string' typeof(123); // 'number' typeof(NaN); // 'number' typeof(cc); // 'undefined' 未定义变量undefined typeof(undefined); // 'undefined' typeof(true); // 'boolean' typeof(null); // 'object' 引用类型:function是特殊类型,能够直接用typeof来判断是不是function。 typeof([]); // 'object' typeof({}); // 'object' typeof(function(){}); // 'function'
alert({name: 'aa'} instanceof Object); // true alert([1, 2] instanceof Array); // true alert(function(){} instanceof Function); // true alert([1, 2] instanceof Object); // true 全部引用类型的值都是Object的实例,所以单独的判断instanceof Object并不能区分是数组,仍是函数等,instanceof应该用来检测真正的对象实例。 alert(13 instanceof Number); // false 使用instanceof检测基本类型的值,始终返回false,由于基本类型不是对象。 new Number(12) instanceof Number; // true
https://www.zhihu.com/questio...
https://www.cnblogs.com/focus...
https://www.cnblogs.com/telne...
https://www.jianshu.com/p/585...spa