JavaScript null和undefined 类型
null和undefined
undefined类型只有一个值,就是undefined;null类型也只有一个值就是null;它们的名称既是类型也是值;
var js;
console.log(js);//undefined
console.log(typeof undefined);//undefined
console.log(typeof typeof undefined);//string
形式
- null是空值,是一个空指针,一般表示一个变量定义了但是没有值(值为空);
- undefined是未定义;
console.log(xxx);// xxx is not defined
和下面
var xxx;
console.log(xxx)
两者是不一样的;
// var NULL=2;
console.log(typeof null);//object 这是一个空的指针;
console.log(typeof NULL);// NULL- >undefined
//结果是undefined 除了用在typeof外,会报错;
console.log(undefined*15);//NaN
// console.log(undefined*aa);//aa is not defined
// console.log(NULL+15);//NULL is not defined 相当于NULL 这个变量没有找到;
没有找到对象的属性,也是undefined;
var msg={
msg1:1,
mag2:2
};
console.log(msg.msg1);//1
console.log(msg.msg3);//undefined
特性
undefined
// 对象的属性
var oDemo={
// aaa:"这是oDemo的aaa值"
};
oDemo.bbb="Hello";
console.log(oDemo.aaa);//undefined
console.log(oDemo.bbb);//Hello
//function 返回值 默认是undefined;
function demo() {
return;
}
var aDemo=demo();
console.log(aDemo);//undefined
null
//ByIn
var oDiv1=document.getElementById("div1"),
oDiv2=document.getElementById("div2");
console.log(oDiv1);
console.log(oDiv2);//null
总结
- null(空值,曾经赋过值,但是目前没有值)
- 逻辑上null表示一个空对象的指针
- 使用typeof检测的时候会返回object;(object原型的终点也是null)
- undefined(没有值,指从没有赋过值)
- 使用var声明变量但没有初始化/赋值的
- 区分空对象指针与尚未定义的变量
- 对未初始化的变量以及未声明的变量使用typeof运算符均会返回undefined;
在非严格模式和严格模式下,我们可以声明一个undefined的局部变量,因为undefined是一个标识符,可以当作变量来使用和赋值;但却不能声明一个null的局部变量,因为null是一个特殊关键字,并不是一个标识符;注意这是为了深入理解null和undefined的背后原理而挖出来的不同,请不要真的声明一个undefined的变量(这是一个非常不好的习惯,严格点的压缩工具,压缩时都不会给你通过的,直接给你抛Error;)
undefined和null的关系;
//null和undefined比较
/*
* === 相同比较,首先判断是否是同一个类型;不是的话,直接false;
* == 比较是否相等;(如果是不一样的类型,会转为相同的类型,然后再进比较)
* */
console.log(null == null);//true
console.log(null == undefined);//true
console.log(undefined == undefined);//true
console.log(undefined === undefined);//true
console.log(null === undefined);//false null->Null undefined -> Undefined
console.log(false == 0);//true false->0 0==0? true
console.log(Number("22") == 22);//true "22"隐士的调用Number->22 -> 22== 22 -> true
console.log("---------------------------");
console.log(null == 1);//false
console.log(null == "2312312");//false
console.log(null == false);//false
console.log(null == 0);//false
console.log(null == "");//false
console.log(null == NaN);//false
console.log("++++++++++++++++++++++++++");
console.log(undefined == 1);//false
console.log(undefined == "2312312");//false
console.log(undefined == false);//false
console.log(undefined == 0);//false
console.log(undefined == "");//false
console.log(undefined == NaN);//false
undefined派生自null;因为undefined派生自null;
所以Null和undefined做比较的时候是true;但是null和undefined和别的任何类型比较都不想等;
- undefined派生子null,因此在使用
==
进行比较的时候会返回true; - 没有必要将变量显示声明undefined;
- 声明非空对象对应将其赋值为null; - 比如做定时器的时候用timer=null来重置变量;
Undefined类只有一个值,就是特殊的undefine;(大写的Undefined是代表Undefined类的意思,就好比人类和人的关系;)
var test1;
var test2=undefined;
console.log(test1==undefined); //true,变量声明了,但是没有定义;
console.log(test1=="undefined");//false,"undefined"是一个字符串,含有undefined的字符;而不是undefined类型;
console.log(test2==undefined); //true,变量声明了,但是没有被定义,undefined是变量的默认值;
//我们声不需要显示的把某个变量设置为undefined,因为没有赋值的变量,默认就是undefined;
//可以试验下,这里的两个等于号和三个等于号的区别,
//2个是比较(会隐式转换类型,===是不转化类型的,是绝对相等)
console.log(test1); //undefined
console.log(test2); //undefined
console.log(test3); //Error,报错了; Uncaught ReferenceError: test3 is not defined;
//对于尚未声明的变量,只能执行一项操作,就是typeof检测其数据类型;
//(对未经声明的变量调用delete也不会导致错误,但属于脱裤子放屁,没啥意义,
//而且在严格模式下确实会导致错误;)
Null是第二个只有一个值的数据类型,这个特殊的值是null,从逻辑上来看,null值表示一个空对象指针,而这也正是typeof操作符检测null时候,返回"object"的原因;
只要意在保存对象的变量还没有真正保存对象,就应该明确的让变量赋值为null值;这不仅可以体现null作为空对象指针的惯例,而且也有助于进一步却分null和undefined;
null的用处
如果你把null
或者undefined
作为this的绑定对象传入 call/apply或者bind,这些值在调用时都会被忽略,实际应用的是默认的绑定规则
function foo(){
console.log(this.a)
}
var a = 2;
foo.call(null); //2
定时器的变量
let timer = null;
timer = setTimeout(function(){
alert("Hello")
},3000);
timer可以用来清除定时器的时候使用,一般清除定时器后最好把 timer 手动置为null;
占this的指向位置
非常常见的做法是 call/apply或者bind 时候使用
function foo(a,b){
console.log(`a:${a},b:${b}`);
}
//把数组展开成参数
foo.apply(null,[2,3]);//a:2,b:3
//使用bind进行柯里化
var bar = foo.bind(null,2);
bar(3);//a:2,b:3
这两种方法都需要传入一个参数当作this绑定对象,如果函数不关心this指向的化,你仍然需要传一个占位值,这时候null可能是一个不错的选择;
在ES6里可以用...
操作符代替apply(..)
;
注意:这种传参是基于this没有用的情况,如果你不确定this是否被使用,这么使用,可能会导致会把this绑定到全局对象(在浏览器种就是windows),可能会导致不可预计的后果(比如修改全局对象)
这时候可以传入一个空对象{}
或者Object.create(null)
Object.create(null)
和 {}
很像,但是并不会创建Object.prototype
这个委托,所以它比{}更空;
undefined可能出现的错误
如果一个变量可能是不存在的,那么一定不要直接使用;
//错误的,可能抛错
if(DEBUG){
console.log('debuging is starting');
}
//安全的
if(typeof DEBUG !== 'undefined'){
console.log('debuging is starting');
}
//安全借助windows属性判断
if(windows.DEBUG){
console.log('debuging is starting');
}