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');
}

AXIHE / 精选资源

浏览全部教程

面试题

学习网站

前端培训
自己甄别

前端书籍

关于朱安邦

我叫 朱安邦,阿西河的站长,在杭州。

以前是一名平面设计师,后来开始接接触前端开发,主要研究前端技术中的JS方向。

业余时间我喜欢分享和交流自己的技术,欢迎大家关注我的 Bilibili

关注我: Github / 知乎

于2021年离开前端领域,目前重心放在研究区块链上面了

我叫朱安邦,阿西河的站长

目前在杭州从事区块链周边的开发工作,机械专业,以前从事平面设计工作。

2014年底脱产在老家自学6个月的前端技术,自学期间几乎从未出过家门,最终找到了满意的前端工作。更多>

于2021年离开前端领域,目前从事区块链方面工作了