基本类型和引用类型值类型(基本类型):String,Number,Boolean,Null,Undefined。引用类型:Array、Object、Function、Date等由多个值组成的变长复杂类型。原始类型和引用类型有什么区别?(1)基本类型变量存放变量值,引用类型变量存放内存地址;(2)基本类型长度固定,在内存中占用固定大小的空间,数据存放在栈内存中;引用类型可以给对象添加属性和方法,长度不固定,数据存放在堆内存中。引用类型的存储需要由栈区和堆区完成(堆区是指内存中的堆内存)。栈区内存存放变量标识符和指向堆内存中对象的指针。也可以说对象在堆内存中。(3)基本类型在赋值时复制值,引用类型在赋值时只复制地址,不复制值。基本类型和引用类型的复制constnum1=5;常量num2=num1;常量obj1={};常量obj2=obj1;基本类型的复制和引用类型的复制,不懂就上代码吧!!//测试引用类型按值传递和数组类型按值传递constobj={success:false,result:{name:'222'}};letname=obj&&obj.result&&obj.result.name;//name是Astr,具体取值是基本类型,这里的name保存的是变量值,不是引用地址console.log(name);//222name="333";console.log(obj.result.name);//222,name是一个变量值,name的改变不会影响obj.result.nameobj.result.name="44444";console.log(obj.result.name);//44444console.log(名字);//333、name是变量值,不是引用地址,与obj.result.name互不影响,所以obj.result.name的改变不会引起name的改变constobj={success:false,result:{name:'222'}};letresult=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和obj.result指向不同的地址,不再相互影响。result={name:'oooooo'};console.log(result);//{name:'oooooo'}console.log(obj.result);//{name:'xxxxx'}constobj={success:false,result:[0,1]};letresult=obj&&obj.result;console.log(result);//[0,1],obj.result是Array类型,result和obj.result在堆中指向同一个地址,相互影响console.log(obj.result);//[0,1]result.push('aa');//数组的入栈操作是在原数组的基础上进行的,不会产生新的数组。result和obj.result仍然指向同一个地址并且相互影响console.log(result);//[0,1,'aa']console.log(obj.result);//[0,1,'aa']结果=[0,1,2];//结果被重新赋值。这时,结果指向了堆中的一个新地址。result和obj.result指向不同的地址,不再相互影响。控制台日志(obj.result);//[0,1,'aa']控制台。日志(结果);//[0,1,2]函数参数按值类型还是引用类型传递?基本类型参??数的传递和基本类型的拷贝一样,传递的是变量值functionaddTen(num){num=num+10;返回num;}varcount=20;varresult=addTen(count);console.log(count);//20console.log(结果);//30引用类型参数的传递和引用类型的拷贝一样,传递的是内存地址。函数setName(obj){obj.name='xxx';obj={名称:'ppp'};//obj指向新地址,person不再指向同一个地址console.log(obj.name);//'ppp'}constperson={name:'oo'};setName(person);console.log(person.name);//'xxx'官方解释:ECMAScript中所有函数的参数都是按值传递的。也就是说,将函数外部的值复制到函数内部的参数与将值从一个变量复制到另一个变量相同。基本类型的传递与基本类型的复制相同,引用类型的值的传递与引用类型变量的复制相同。总结很简单,javascript函数参数是按值传递的(都是栈中数据的副本)。基本类型传递的是值本身(因为值直接存放在栈中),引用类型传递的是对象在内存中的地址(因为复杂对象存在于堆中,对象的堆地址存放在堆栈)。基本类型和引用类型的检测typeof是检测基本数据类型最好的工具,但是检测引用类型,返回的都是对象,无法判断是哪种类型的对象,没有意义。基本类型:基本类型中的null会作为object返回,其他的可以正常检测到正确的类型。typeof('aa');//'字符串'typeof(123);//'数字'typeof(NaN);//'数字'typeof(cc);//'undefined'undefined变量undefinedtypeof(undefined);//'undefined'typeof(true);//'布尔'typeof(null);//'object'引用类型:function是一种特殊类型,可以直接用typeof判断是否是函数。类型([]);//'对象'typeof({});//'object'typeof(function(){});//'function'typeof总结:instanceof操作符可以专门用来检测引用类型,判断当前对象是什么类型的对象。alert({name:'aa'}instanceofObject);//truealert([1,2]instanceofArray);//truealert(function(){}instanceofFunction);//truealert([1,2]instanceofObject);//true引用类型的所有值都是Object的实例,所以单靠判断instanceofObject无法区分是数组还是函数等,应该使用instanceof来检测真实的对象实例。警报(13instanceofNumber);//false使用instanceof检测基本类型的值,总是返回false,因为基本类型不是对象。newNumber(12)instanceofNumber;//truejavascript最准确方便的方法:参考https://www.zhihu.com/questio...https://www.cnblogs.com/focus...https://www.cnblogs.com/telne...https://www.jianshu.com/p/585...
