为啥 null 是一个对象,null 和 undefined 有啥区别?
Posted
技术标签:
【中文标题】为啥 null 是一个对象,null 和 undefined 有啥区别?【英文标题】:Why is null an object and what's the difference between null and undefined?为什么 null 是一个对象,null 和 undefined 有什么区别? 【发布时间】:2010-10-22 12:14:31 【问题描述】:为什么 null
在 javascript 中被视为 object
?
正在检查
if ( object == null )
Do something
和
一样if ( !object )
Do something
?
还有:
null
和 undefined
有什么区别?
【问题讨论】:
Null 不是 JavaScript 中的对象!typeof null === 'object'
但这是一个错误!这是link 观看所有视频并享受:)
我喜欢使用 C/C++ 作为未定义和 NULL 值变量的公理真理,因为它非常简单。然后看看这些定义与其他语言的规范相比如何。
【参考方案1】:
(name is undefined)
你:什么是name
? (*)JavaScript: name
? name
是什么?我不知道你在说什么。您之前从未提及任何name
。您是否在(客户端)端看到了其他一些脚本语言?
name = null;
你:什么是name
?JavaScript:我不知道。
简而言之; undefined
是不存在事物概念的地方;它没有类型,并且以前从未在该范围内引用过; null
是已知事物存在的地方,但不知道它的价值是什么。
要记住的一点是,null
在概念上与 false
或 ""
等不同,即使它们在类型转换之后等同,即
name = false;
你:什么是name
?JavaScript:布尔假。
name = '';
你:什么是name
?JavaScript:空字符串
*:name
在此上下文中表示为从未定义过的变量。它可以是任何未定义的变量,但是,name 几乎是任何 html 表单元素的属性。它可以追溯到很久以前,并且在 id 之前就已经建立了。它很有用,因为 id 必须是唯一的,但名称不必是唯一的。
【讨论】:
但在 JavaScript 中,空字符串 '' 仍然是布尔值 false。 空字符串不是布尔值 false,但在条件上下文中它被解释为 false(y) 值(强制)。 对于第二种情况,其中 name = null,而不是“我不知道”,JavaScript 可以回答:空对象。除此之外,我喜欢答案的风格。 与其说“我不知道”,不如说null
的答案是“什么都没有”。 Null 被精确定义为没有值。无效,无,无。什么都没有。
喜欢这种回答方式。一般来说,“你从来没有提到过任何 name
之前” 是正确的。然而,声明一个变量而不给它赋值(var somevar;
),仍然会令人惊讶地导致undefined
。【参考方案2】:
区别可以总结成这个sn-p:
alert(typeof(null)); // object
alert(typeof(undefined)); // undefined
alert(null !== undefined) //true
alert(null == undefined) //true
检查
object == null
与if ( !object )
不同。
后者等于! Boolean(object)
,因为一元!
运算符自动将右操作数转换为布尔值。
因为Boolean(null)
等于假,那么!false === true
。
所以如果你的对象是not null, but false or 0 or "",检查将通过 因为:
alert(Boolean(null)) //false
alert(Boolean(0)) //false
alert(Boolean("")) //false
【讨论】:
@kentaromiura 对我们来说 Javascript 菜鸟......也许只有我......这个 Boolean(value) 语法是什么?转换为布尔值? @xr280xr 是的,它正在铸造。尝试String(null)
以查看另一个投射示例。你甚至可以做一些愚蠢的事情,比如Number(null + 2)
... 但你不应该:-)。 kentaromiura 的出色回答。
记住typeof
是一个操作员。您不会将操作数括在括号中,原因与您不会写 var sum = 1 +(1);
的原因相同。【参考方案3】:
null
是not an object,它是一个原始值。例如,您不能向其添加属性。有时人们错误地认为它是一个对象,因为typeof null
返回"object"
。但这实际上是一个错误(甚至可能在 ECMAScript 6 中修复)。
null
和undefined
的区别如下:
undefined
:被 JavaScript 使用,意思是“没有价值”。未初始化的变量、缺失的参数和未知变量都有那个值。
> var noValueYet;
> console.log(noValueYet);
undefined
> function foo(x) console.log(x)
> foo()
undefined
> var obj = ;
> console.log(obj.unknownProperty)
undefined
但是,访问未知变量会产生异常:
> unknownVariable
ReferenceError: unknownVariable is not defined
null
:程序员用来表示“无价值”,例如作为函数的参数。
检查变量:
console.log(typeof unknownVariable === "undefined"); // true
var foo;
console.log(typeof foo === "undefined"); // true
console.log(foo === undefined); // true
var bar = null;
console.log(bar === null); // true
作为一般规则,您应该始终在 JavaScript 中使用 === 而永远不要 ==(== 执行all kinds of conversions 可能会产生意外结果)。检查x == null
是一种极端情况,因为它适用于null
和undefined
:
> null == null
true
> undefined == null
true
检查变量是否有值的常用方法是将其转换为布尔值并查看它是否为true
。该转换由if
语句和布尔运算符执行! (“不是”)。
function foo(param)
if (param)
// ...
function foo(param)
if (! param) param = "abc";
function foo(param)
// || returns first operand that can't be converted to false
param = param || "abc";
这种方法的缺点:以下所有值都计算为false
,因此您必须小心(例如,上述检查无法区分undefined
和0
)。
undefined
, null
布尔值:false
号码:+0
、-0
、NaN
字符串:""
您可以通过将Boolean
用作函数来测试到布尔值的转换(通常它是一个构造函数,与new
一起使用):
> Boolean(null)
false
> Boolean("")
false
> Boolean(3-3)
false
> Boolean()
true
> Boolean([])
true
【讨论】:
如果+0 === -0
,为什么要分别引用+0
和-0
?
可能是因为你还能区分+0
和-0
:1/+0 !== 1/-0
。
这个答案链接到一个帖子,该帖子链接回这个答案作为来源......可能意味着链接到这个而不是2ality.com/2013/10/typeof-null.html
哦,对了,就像在 C 中一样,未初始化的变量声明被认为是未定义的(旧版本实际上可能包含以前的程序数据)。
“但这实际上是一个错误(甚至可能在 ECMAScript 6 中修复)”——来源?【参考方案4】:
null 和 undefined 有什么区别??
没有定义的属性是undefined
。 null
是一个对象。它的类型是object
。 null 是一个特殊的值,意思是“没有值。undefined 不是一个对象,它的类型是未定义的。
您可以声明一个变量,将其设置为 null,其行为是相同的,只是您会看到打印出的“null”与“undefined”。您甚至可以将未定义的变量与 null 进行比较,反之亦然,条件为真:
undefined == null
null == undefined
详情请参阅JavaScript Difference between null and undefined。
以及您的新编辑 是
if (object == null) does mean the same if(!object)
在测试object
是否为假时,它们都只在测试if false时满足条件,但在true时不满足
在这里查看:Javascript gotcha
【讨论】:
你应该使用 ===,然后 undefined !== null :D 注意最后一部分,不正确的看我的回答;) !object 与 "object == null" 不同......事实上,它们完全不同。 !object 将返回 true 如果对象为 0、空字符串、布尔 false、未定义或 null。 null 真的是一个对象吗?您提供的第一个链接通过 typeof 检查 null,但由于语言设计错误,typeof(null) 评估为“object”。null
不是一个对象。 typeof null == 'object';
返回 true 是因为 JavaScript 中无法修复的错误(目前,但将来可能会更改)。【参考方案5】:
问题的第一部分:
为什么 null 在 JavaScript 中被视为对象?
这是他们现在无法修复的 JavaScript 设计错误。它应该是 null 类型,而不是 object 类型,或者根本没有它。在检测真实物体时需要进行额外的检查(有时会被遗忘),并且是错误的来源。
问题的第二部分:
正在检查
if (object == null)
Do something
同if (!object)
Do something
这两个检查总是都是假的,除了:
对象未定义或为空:均为真。
对象是原始的,0,""
,或假:先检查假,后检查真。
如果对象不是原始对象,而是真正的对象,例如 new Number(0)
、new String("")
或 new Boolean(false)
,那么这两个检查都是错误的。
所以如果'object'被解释为一个真正的对象,那么两个检查总是相同的。如果允许使用原语,则对 0、""
和 false 的检查是不同的。
在像object==null
这样的情况下,不明显的结果可能是错误的来源。不建议使用==
,而是使用===
。
问题的第三部分:
还有: null 和 undefined 有什么区别?
在 JavaScript 中,一个区别是 null 是 object 类型,而 undefined 是 undefined 类型。
在 JavaScript 中,null==undefined
为真,如果忽略类型,则认为相等。为什么他们决定这样做,但 0、""
和 false 不相等,我不知道。这似乎是一个武断的意见。
在 JavaScript 中,null===undefined
不正确,因为 ===
中的类型必须相同。
实际上,null 和 undefined 是相同的,因为它们都表示不存在。 0 和""
也是如此,也许还有空容器[]
和。这么多类型的相同无是错误的秘诀。一种或根本没有更好。我会尽量少用。
“假”、“真”和“!”是另一个可以简化的蠕虫包,例如if(!x)
和if(x)
就足够了,你不需要真假。
如果没有给出值,则声明的var x
是未定义类型,但它应该与根本没有声明 x 相同。另一个错误来源是一个空的空容器。所以最好一起声明和定义,比如var x=1
。
人们绕着圈子转来转去,试图找出所有这些不同类型的虚无,但在复杂的不同衣服中都是一样的东西。现实是
undefined===undeclared===null===0===""===[]======nothing
也许所有人都应该抛出异常。
【讨论】:
很好的答案,但是 [] 有点过分了:“实际上,null 和 undefined 是相同的......而且可能是空容器 [] 和 。 i>" 你可能会说服我认为 应该是某种 null 的味道,但我的直觉是它不应该。但争议较少,空数组[]
可以理解有一个.push()
函数,所以没有很好的理由证明[] 为null。 0.02 美元。
谢谢。我觉得这比选择的答案更好地回答了原始问题。我希望任何人都可以详细说明“这是一个他们现在无法修复的 JavaScript 设计错误”并链接到文档,准确解释为什么 javascript 会以这种方式运行?
这不是设计错误(见my answer)。【参考方案6】:
typeof null; // object
typeof undefined; // undefined
值 null 表示有意不存在任何对象值。它是 JavaScript 的原始值之一,在布尔运算中被视为虚假值。
var x = null;
var y;
x 被声明并定义为 null
y 已声明但未定义。它被声明为没有值,因此它是未定义的。
z 没有被声明,所以如果你尝试使用 z 也会是未定义的。
【讨论】:
这个答案将 undeclared 与undefined
混为一谈。【参考方案7】:
理解 null 和 undefined 的一种方法是了解它们出现的位置。
在以下情况下期望返回空值:
查询 DOM 的方法
console.log(window.document.getElementById("nonExistentElement"));
//Prints: null
从 Ajax 请求收到的 JSON 响应
name: "Bob",
address: null
RegEx.exec.
新功能处于不断变化的状态。以下返回null:
var proto = Object.getPrototypeOf(Object.getPrototypeOf());
// But this returns undefined:
Object.getOwnPropertyDescriptor(, "a");
所有其他不存在的情况都用 undefined 表示(如 @Axel 所述)。以下每个打印“未定义”:
var uninitalised;
console.log(uninitalised);
var obj = ;
console.log(obj.nonExistent);
function missingParam(missing)
console.log(missing);
missingParam();
var arr = [];
console.log(arr.pop());
当然,如果你决定写 var unitialised = null;或自己从方法返回 null 然后在其他情况下会出现 null 。但这应该很明显。
第三种情况是当您想要访问一个变量但您甚至不知道它是否已被声明时。对于这种情况,请使用 typeof 来避免引用错误:
if(typeof unknown !== "undefined")
//use unknown
在您操作 DOM、处理 Ajax 或使用某些 ECMAScript 5 功能时,总而言之检查 null。对于所有其他情况,使用严格相等检查 undefined 是安全的:
if(value === undefined)
// stuff
【讨论】:
【参考方案8】:JavaScript 中许多不同的 null 检查的比较:
http://jsfiddle.net/aaronhoffman/DdRHB/5/
// Variables to test
var myNull = null;
var myObject = ;
var myStringEmpty = "";
var myStringWhiteSpace = " ";
var myStringHello = "hello";
var myIntZero = 0;
var myIntOne = 1;
var myBoolTrue = true;
var myBoolFalse = false;
var myUndefined;
...trim...
http://aaron-hoffman.blogspot.com/2013/04/javascript-null-checking-undefined-and.html
【讨论】:
执行“var myUndefined;”定义变量(作为未知类型的已知变量)?【参考方案9】:TLDR
undefined
是 JavaScript 中的原始值,表示值的隐式缺失。未初始化的变量自动具有此值,并且没有显式 return
语句的函数返回 undefined
。
null
也是 JavaScript 中的原始值。它表示the intentional absence of an object value。 JavaScript 中的null
旨在实现与Java 的互操作性。
typeof null
返回"object"
是因为该语言设计的特殊性,源于 JavaScript 与 Java 可互操作的需求。这并不意味着null
是一个对象的实例。这意味着:给定 JavaScript 中的原始类型树,null
是“对象类型原始”子树的一部分。这将在下面更全面地解释。
详情
undefined
是一个原始值,represents 隐含没有值。请注意,直到 1998 年的 JavaScript 1.3,undefined
才能直接访问。这告诉我们,null
旨在成为程序员在明确指示缺少值时使用的值。未初始化的变量自动具有值undefined
。 undefined
是 ECMAScript 规范中的 one-of-a-kind type。
null
是一个原始值,represents 故意缺少对象值。 null
也是 ECMAScript 规范中的 one-of-a-kind type。
JavaScript 中的null
旨在实现与Java、both from a "look" perspective, and from a programatic perspective (eg the LiveConnect Java/JS bridge planned for 1996) 的互操作性。此后,Brendan Eich 和其他人都对包含 两个“缺乏价值”的值表示反感,但在 1995 年,Eich 是 under orders,以“让 [JavaScript] 看起来像 Java”。
Brendan Eich:
如果我没有“让它看起来像 Java”作为管理层的命令, 并且我有更多的时间(很难混淆这两个因果因素),然后我会更喜欢自我般的“一切都是对象” 方法:没有布尔、数字、字符串包装器。没有未定义和空值。 叹息。
为了适应 Java 的 null
概念,由于 Java 的强类型特性,它只能分配给类型为引用类型(而不是原语)的变量,Eich 选择定位特殊的 null
值位于对象原型链的顶部(即引用类型的顶部),并将 null
类型作为“对象类型原语”集的一部分。
typeof
运算符随后不久被添加 in JavaScript 1.1,于 1996 年 8 月 19 日发布。
来自the V8 blog:
typeof null
返回object
,而不是null
,尽管null
是 自己的类型。为了理解为什么,考虑所有的集合 JavaScript 类型分为两组:对象(即对象类型) 基元(即任何非对象值)
因此,
null
表示“没有对象值”,而undefined
表示“没有 价值”。
遵循这一思路,Brendan Eich 设计了 JavaScript 以 使
typeof
为右侧的所有值返回“对象”, 即所有对象和空值,本着 Java 的精神。这就是为什么typeof null === 'object'
尽管规范有一个单独的null
类型。
因此,Eich 设计了原始类型的层次结构以实现与 Java 的互操作性。这导致他将null
与“对象类型原语”一起定位在层次结构上。为了反映这一点,在不久之后将typeof
添加到语言中时,他选择了typeof null
以返回"object"
。
JavaScript 开发人员在 typeof null === "object"
表达的惊讶是由具有 null
和 undefined
的弱类型语言 (JavaScript) 与另一种强类型语言 (JavaScript) 之间的阻抗不匹配(或抽象泄漏)造成的 -只有 null
的类型化语言 (Java),其中 null
是 strictly defined 以引用引用类型(不是原始类型)。
请注意,这一切都是合乎逻辑的、合理的和可辩护的。 typeof null === "object"
不是错误,而是必须适应 Java 互操作性的二阶效应。
出现了许多不完美的反向合理化和/或约定,包括undefined
表示隐式缺少值,null
表示有意不存在有价值的;或者 undefined
是没有值,null
是没有 object 值。
与 Brendan Eich 的相关对话,截图供后人参考:
【讨论】:
yes undefined 表示变量已声明但未初始化为任何值或对象的引用。变量 x; //现在 x 的值实际上是未定义的 COMPARE TO var x; x = 空; //现在x的值为null。 Null 只是一种类似于数字和字符串的愚蠢类型的对象,可以用作占位符。未定义意味着它没有被初始化为任何值【参考方案10】:补充undefined
和null
的区别是什么,来自JavaScript Definitive Guide 6th Edition, p.41 on this page:
您可能会认为
undefined
代表系统级别的、意外的、 或类似错误的价值缺失和null
表示程序级别, 正常,或预期没有价值。如果您需要分配其中之一 将这些值传递给变量或属性,或将这些值之一传递给 一个函数,null
几乎总是正确的选择。
【讨论】:
【参考方案11】:null 和 undefined 对于值相等(null==undefined)都是 false:它们都折叠为布尔 false。它们不是同一个对象(null!==undefined)。
undefined 是全局对象(浏览器中的“窗口”)的属性,但它是原始类型而不是对象本身。它是未初始化的变量和没有返回语句结束的函数的默认值。
null 是 Object 的一个实例。 null 用于返回集合对象以指示空结果的 DOM 方法,它提供 false 值而不指示错误。
【讨论】:
null
不是Object
的实例。【参考方案12】:
一些精度:
null 和 undefined 是两个不同的值。一个表示没有名称的值,另一个表示没有名称。
if
中发生的情况如下:if( o )
:
计算括号 o 中的表达式,然后 if
开始强制类型强制括号中表达式的值 - 在我们的例子中为 o
。
JavaScript 中的 Falsy(将被强制为 false)值是:''、null、undefined、0 和 false。
【讨论】:
【参考方案13】:以下函数说明了原因并能够解决差异:
function test()
var myObj = ;
console.log(myObj.myProperty);
myObj.myProperty = null;
console.log(myObj.myProperty);
如果你打电话
test();
你得到了
未定义
空
第一个console.log(...)
尝试从myObj
获取myProperty
,而它尚未定义 - 所以它返回“未定义”。将 null 分配给它后,第二个 console.log(...)
显然返回“null”,因为 myProperty
存在,但它具有分配给它的值 null
。
为了能够查询这种差异,JavaScript 有 null
和 undefined
:而 null
是 - 就像在其他语言中的对象一样,undefined
不能是对象,因为没有实例(甚至没有null
实例)可用。
【讨论】:
【参考方案14】:例如window.someWeirdProperty
是未定义的,所以
"window.someWeirdProperty === null"
计算结果为 false 而
"window.someWeirdProperty === undefined"
计算结果为真。
此外,检查if (!o)
与检查if (o == null)
是否为o
是false
不同。
【讨论】:
能否详细说明这两种情况的区别 阅读我的答案,他的意思是如果 o 等于 0,false 或 "" 布尔值为 false:var undef, various =[0,"",null,false,undef]; for(var obj in various) alert(!obj); // IE 中 4 次 false,FF 中 5 次 ;) 【参考方案15】:在 Javascript 中,null
不是 object
类型,而是 primitave
类型。
有什么区别?
Undefined 指的是一个没有被设置的指针。
Null 指的是空指针,例如某些东西已手动将变量设置为null
类型
【讨论】:
【参考方案16】:看看这个:
<script>
function f(a)
alert(typeof(a));
if (a==null) alert('null');
a?alert(true):alert(false);
</script>
//return:
<button onclick="f()">nothing</button> //undefined null false
<button onclick="f(null)">null</button> //object null false
<button onclick="f('')">empty</button> //string false
<button onclick="f(0)">zero</button> //number false
<button onclick="f(1)">int</button> //number true
<button onclick="f('x')">str</button> //string true
【讨论】:
【参考方案17】:来自 Nicholas C. Zakas 的“面向对象 Javascript 的原理”
但是当类型为空时为什么是一个对象呢? (事实上,设计和维护 JavaScript 的委员会 TC39 已经承认这是一个错误。你可以推断 null 是一个空对象指针,使“对象”成为一个逻辑返回值,但这仍然令人困惑。)
扎卡斯,尼古拉斯 C. (2014-02-07)。面向对象 JavaScript 的原理(Kindle Locations 226-227)。没有淀粉出版社。 Kindle版。
也就是说:
var game = null; //typeof(game) is "object"
game.score = 100;//null is not an object, what the heck!?
game instanceof Object; //false, so it's not an instance but it's type is object
//let's make this primitive variable an object;
game = ;
typeof(game);//it is an object
game instanceof Object; //true, yay!!!
game.score = 100;
未定义的情况:
var score; //at this point 'score' is undefined
typeof(score); //'undefined'
var score.player = "felix"; //'undefined' is not an object
score instanceof Object; //false, oh I already knew that.
【讨论】:
【参考方案18】:null
是一个对象。它的类型为空。 undefined
不是对象;它的类型是未定义的。
【讨论】:
错误 -null
和 undefined
都是原始值 - typeof null === 'object'
是一个语言错误,因为 Object(null) !== null
不,不是。 Object() 以这种方式进行转换,请参阅 ecma-international.org/publications/files/ECMA-ST/Ecma-262.pdf -- 15.2.2.1 new Object ( [ value ] ) ... 8. (未提供参数值或其类型为 Null 或 Undefined。)创建一个新的本机ECMAScript 对象。新建对象的 [[Prototype]] 属性设置为 Object 原型对象。新建对象的 [[Class]] 属性设置为“Object”。新构造的对象没有 [[Value]] 属性。返回新创建的原生对象。
@Christoph:我的意思是,你是对的。 null 应该 是一个类型,我的意思是你不能以这种方式检查它,因为:alert(new Object() !== new Object()); /* true, new istance 与 istance 不同/ alert(Object(null).constructor == .constructor); / true 如规范 / alert(Object(null).prototype == .prototype); / true 如规范 / alert(null instanceof Object); / 显然是错误的,null 表示未实例化 */ 但基本上是规范错误 XD 参见:uselesspickles.com/blog/2006/06/12/… 和 javascript.crockford.com/remedial.html【参考方案19】:
考虑“null”的最佳方式是回想数据库中如何使用类似概念,它表示字段包含“根本没有值”。
是的,物品的价值是已知的;它是“定义的”。它已经被初始化了。 项目的价值是:“没有价值。”对于编写更容易调试的程序来说,这是一种非常有用的技术。一个“未定义”的变量可能是一个错误的结果……(你怎么知道?)……但是如果变量包含值“null”,你就知道“某人,某处在这个程序中,设置它为'null'。”因此,我建议,当你需要删除一个变量的值时,不要“删除”......将它设置为'空值。'旧值将被孤立,很快将被垃圾回收;新的价值是,“没有价值(现在)。”在这两种情况下,变量的状态都是确定的:“它显然是故意的。”
【讨论】:
【参考方案20】:与 undefined 相比,null 的另一个有趣之处在于它可以递增。
x = undefined
x++
y = null
y++
console.log(x) // NaN
console.log(y) // 0
这对于设置计数器的默认数值很有用。您在声明中将变量设置为 -1 多少次?
【讨论】:
【参考方案21】:-
未定义表示变量已声明但尚未赋值,而 Null 可以赋值给表示“无值”的变量。(Null 是赋值运算符)
2.Undefined 本身是一个类型,而 Null 是一个对象。
3.Javascript 本身可以将任何未分配的变量初始化为 undefined,但它永远不能将变量的值设置为 null。这必须以编程方式完成。
【讨论】:
【参考方案22】:使用 null 将某事定义为没有值,如果您认为某事可能根本没有定义,则使用 undefined。
例如,如果一个变量没有值,则将其赋值为 null。
var weDontHaveAValue = null;
如果您希望某些内容可能根本没有定义,例如一个可选的选项参数,使用 undefined。
if (typeof args.optionalParam !== 'undefined')
【讨论】:
以上是关于为啥 null 是一个对象,null 和 undefined 有啥区别?的主要内容,如果未能解决你的问题,请参考以下文章
为啥我从 Dapper 返回的对象具有 null 和默认属性值?
为啥我得到 null 而不是 Map 对象?如何解决这个问题?
为啥 Spring 安全身份验证返回 Null 身份验证对象?
php artisan optimize NULL.ERROR: Symfony\Component\Debug\Exception\FatalThrowableError: Call to unde