undefined:undefined的字面意思是:未定义的值。这个值的语义是代表一个变量最原始的状态,而不是人为操作的结果。这种原始状态会出现在以下4种场景:[1]声明了一个变量,但是没有赋值varfoo;控制台日志(富);//undefined[2]访问对象上不存在的属性console.log(Object.foo);//undefinedvararr=[];console.log([0]);//undefined访问Object对象上foo的属性,返回undefined,这意味着名为foo的属性不存在或未在Object上定义。数组中的元素在内部也属于对象属性。访问下标等同于访问这个属性。返回undefined意味着该元素不存在于数组中。[3]函数定义了形参,但不传递实参//函数定义了形参functionfn(a){console.log(a);//未定义}fn();//不传递实参函数fn定义了形参a,调用fn时不传递任何参数。因此,fn运行时的参数a是一个没有被赋值的原始变量。[4]使用void来计算表达式void0;//undefinedvoidfalse;//未定义无效[];//未定义无效null;//未定义无效函数fn(){};所有的公式求值都返回undefined,这和函数执行完没有返回值的函数是一样的。JavaScript中的函数有返回值。当没有返回操作时,默认返回一个原始状态值,即undefined,表示函数的返回值是undefined。因此,undefined一般来自表达式最原始的状态值,而不是人为操作的结果。当然你也可以手动给一个变量赋值undefined,但是这样做是没有意义的,因为一个变量不赋值就是undefined。nullnull字面意思是:空值。这个值的语义是表示一个对象被人为重置为一个空对象,而不是一个变量的原始状态。在内存中的表现是栈中的变量不指向堆中的内存对象,即当一个对象被赋值为null时,原来的对象在内存中处于空闲状态,而GC会择机回收对象并释放内存。因此,如果需要释放一个对象,将该变量设置为null,表示该对象已经被清空,当前处于无效状态。另一个与null相关的问题需要说明一下:typeofnull=='object'null有自己的类型Null,不是Object类型。typeof之所以被判断为Object类型,是因为JavaScript数据类型都在底层。以二进制形式表示,如果二进制前三位为0,则typeof会判断为object类型,而null的二进制位恰好全为0,因此null被误判为Object类型。000-Object,数据是对象的应用1-Integer,数据是31位有符号整数010-Double类型,数据是双精度数100-String,数据是字符串110-Boolean类型,数据是aBooleanvalue其实我们可以通过另外一个方法获取null的真实类型:Object.prototype.toString.call(null);//[objectNull]可以通过Object原型Type上的toString()方法获取JavaScript中对象的真实数据,当然未定义类型也可以通过这种方式获取:Object.prototype.toString.call(不明确的);//[objectUndefined]相似性虽然undefined和null的语义和场景不同,但总之,它们都代表着一个无效值。因此,在JS中访问此类值的属性时,会得到异常结果:null.toString();//无法读取nullundefined.toString()的属性“toString”;//Cannotreadproperty'toString'ofundefined ECMAScript规范认为,由于null和undefined的行为相似,都代表无效值,所以它们代表的内容也相似,即undefined==null;//true不要尝试转换数据类型来解释这个结论,因为:Number(null);//0号(未定义);//NaN//比较相等前,null不转换为其他类型null==0;//false但是===会返回false,因为同余操作===比较相等时不会主动转换项的数据类型,两者不属于同一类型:undefined===null;//false,类型不相同undefined!==null;//true,不同类型总结一句话总结两者的区别:undefined是指变量自然的、最原始的状态值,而null是指变量被人为设置为空对象,而不是原始状态。因此,在实际使用中,为了保证变量所表示的语义,不要显式地给一个变量赋值undefined。当需要释放一个对象时,可以直接将该值赋值给null。
