在 JavaScript 中使用 null 而不是 undefined 的原因是什么?

发布于 2024-11-18 23:16:56 字数 163 浏览 2 评论 0原文

我已经编写 JavaScript 很长时间了,但我从来没有理由使用 null。似乎 undefined 总是更可取,并且以编程方式达到相同的目的。使用 null 而不是 undefined 的实际原因有哪些?

I've been writing JavaScript for quite a long time now, and I have never had a reason to use null. It seems that undefined is always preferable and serves the same purpose programmatically. What are some practical reasons to use null instead of undefined?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(22

你的他你的她 2024-11-25 23:16:56

我真的没有答案,但根据 Nicholas C. Zakas,他的书第 30 页 "Web 开发人员的专业 JavaScript"

定义变量时的意思是
稍后持有一个物体,它是
建议初始化变量
null 而不是其他任何内容。
这样,您可以显式检查值 null 以确定是否
稍后该变量已被对象引用填充

I don't really have an answer, but according to Nicholas C. Zakas, page 30 of his book "Professional JavaScript for Web Developers":

When defining a variable that is meant
to later hold an object, it is
advisable to initialize the variable
to null as opposed to anything else.
That way, you can explicitly check for the value null to determine if
the variable has been filled with an object reference at a later time

少跟Wǒ拽 2024-11-25 23:16:56

最终,因为 nullundefined 都强制转换为相同的值 (Boolean(undefined) === false && Boolean(null) === false),从技术上讲,您可以使用其中任何一个来完成工作。然而,在我看来,有正确的方法。

  1. undefined 的使用留给 JavaScript 编译器。

    undefined 用于描述不指向引用的变量。这是 JS 编译器会为你处理的事情。在编译时,JS 引擎会将所有提升变量的值设置为 undefined。当引擎逐步执行代码并且值变得可用时,引擎会将相应的值分配给相应的变量。对于那些没有找到值的变量,这些变量将继续维护对基元 undefined 的引用。

  2. 仅当您明确想要将变量的值表示为“无值”时才使用 null。

    正如 @com2gz 所说:null 用于以编程方式定义空的内容。 undefined 表示引用不存在。 null 值定义了对“无”的引用。如果您调用对象的不存在属性,那么您将得到未定义。如果我故意将该属性设置为空,那么它必须为 null,这样您就知道它是故意的。

TLDR; 不要使用undefined 原语。当您声明变量而不进行赋值或尝试访问没有引用的对象的属性时,JS 编译器会自动为您设置该值。另一方面,当且仅当您有意希望变量“无值”时,才使用 null


侧边栏:我个人避免将任何内容显式设置为未定义(并且在我与之交互的许多代码库/第三方库中我还没有遇到过这样的模式) )。另外,我很少使用 null。我唯一使用 null 的时候是当我想将函数的参数值表示为无值时,即:

function printArguments(a,b) {
  console.log(a,b);
}

printArguments(null, " hello") // logs: null hello

At the end of the day, because both null and undefined coerce to the same value (Boolean(undefined) === false && Boolean(null) === false), you can technically use either to get the job done. However, there is right way, IMO.

  1. Leave the usage of undefined to the JavaScript compiler.

    undefined is used to describe variables that do not point to a reference. It is something that the JS compiler will take care for you. At compile time the JS engine will set the value of all hoisted variables to undefined. As the engine steps through the code and values becomes available the engine will assign respective values to respective variables. For those variables for whom it did not find values, the variables would continue to maintain a reference to the primitive undefined.

  2. Only use null if you explicitly want to denote the value of a variable as having "no value".

    As @com2gz states: null is used to define something programmatically empty. undefined is meant to say that the reference is not existing. A null value has a defined reference to "nothing". If you are calling a non-existing property of an object, then you will get undefined. If I would make that property intentionally empty, then it must be null so you know that it's on purpose.

TLDR; Don't use the undefined primitive. It's a value that the JS compiler will automatically set for you when you declare variables without assignment or if you try to access properties of objects for which there is no reference. On the other hand, use null if and only if you intentionally want a variable to have "no value".


Sidebar: I, personally, avoid explicitly setting anything to undefined (and I haven't come across such a pattern in the many codebases/third party libs I've interacted with). Also, I rarely use null. The only times I use null is when I want to denote the value of an argument to a function as having no value, i.e.,:

function printArguments(a,b) {
  console.log(a,b);
}

printArguments(null, " hello") // logs: null hello
心意如水 2024-11-25 23:16:56

nullundefined 本质上是两个不同的值,但含义相同。唯一的区别在于您在系统中使用它们的约定。正如一些人提到的,有些人使用 null 来表示“没有对象”,有时您可能会得到一个对象,而未定义则意味着不需要对象(或者存在错误)。我的问题是它完全是任意的,而且完全没有必要。

也就是说,有一个主要区别 - 未初始化的变量(包括未传递参数的函数参数等)总是未定义。

这就是为什么在我的代码中我从不使用null,除非我无法控制的东西返回null(例如正则表达式匹配)。这样做的好处是它大大简化了事情。我永远不必检查 x === undefined || 是否x === null,我可以检查x === undefined。如果您习惯使用 == 或简单的诸如 if(x) ... 之类的东西,请停止使用。

对于空字符串、0nullNaN!x 的计算结果为 true - 即您可能不这样做的事情不想。如果您想编写不太糟糕的 javascript,请始终使用三重等于 === 并且永远不要使用 null (而是使用 undefined )。它会让你的生活变得更轻松。

null and undefined are essentially two different values that mean the same thing. The only difference is in the conventions of how you use them in your system. As some have mentioned, some people use null for meaning "no object" where you might sometimes get an object while undefined means that no object was expected (or that there was an error). My problem with that is its completely arbitrary, and totally unnecessary.

That said, there is one major difference - variables that aren't initialized (including function parameters where no argument was passed, among other things) are always undefined.

Which is why in my code I never use null unless something I don't control returns null (regex matching for example). The beauty of this is it simplifies things a lot. I never have to check if x === undefined || x === null, I can just check x === undefined. And if you're in the habit of using == or simply stuff like if(x) ..., stop it.

!x will evaluate to true for an empty string, 0, null, NaN - i.e. things you probably don't want. If you want to write javascript that isn't awful, always use triple equals === and never use null (use undefined instead). It'll make your life way easier.

薄情伤 2024-11-25 23:16:56

未定义是指不存在该事物的概念;它没有类型,并且之前从未在该范围内被引用过; null 是已知事物存在的地方,但它没有价值。

undefined is where no notion of the thing exists; it has no type, and it's never been referenced before in that scope; null is where the thing is known to exist, but it has no value.

南城旧梦 2024-11-25 23:16:56

每个人都有自己的编码方式和自己的内部语义,但多年来我发现这是我给提出这个问题的人的最直观的建议:当有疑问时,做 JavaScript 所做的事情

假设您正在使用对象属性(例如 jQuery 插件的选项)...问问自己 JavaScript 为尚未定义的属性赋予什么值 - 答案是 未定义。因此,在这种情况下,我会使用“undefined”初始化这些类型的内容,以与 JavaScript 保持一致(对于变量,您可以执行 var myVar; 而不是 var myVar = undefined;代码>)。

现在假设您正在进行 DOM 操作...JavaScript 为不存在的元素分配什么值?答案是null。如果您要创建一个占位符变量,该变量稍后将保存对与 DOM 相关的元素、文档片段或类似内容的引用,那么我将使用该值进行初始化。

如果您使用 JSON,则需要特殊情况:对于未定义的属性值,您应该将它们设置为 ""null,因为值为undefined 不被视为正确的 JSON 格式。

话虽如此,正如之前的发帖者所表达的那样,如果您发现自己多次使用 nullundefined 初始化内容,那么也许您应该重新考虑如何编写应用程序代码。

Everyone has their own way of coding and their own internal semantics, but over the years I have found this to be the most intuitive advice that I give people who ask this question: when in doubt, do what JavaScript does.

Let's say you are working with object properties like options for a jQuery plugin...ask yourself what value JavaScript gives a property that has yet to be defined -- the answer is undefined. So in this context, I would initialize these types of things with 'undefined' to be consistent with JavaScript (for variables, you can do var myVar; instead of var myVar = undefined;).

Now let's say you are doing DOM manipulation...what value does JavaScript assign to non-existent elements? The answer is null. This is the value I would initialize with if you are creating a placeholder variable that will later hold a reference to an element, document fragment, or similar that relates to the DOM.

If you're working with JSON, then a special case needs to be made: for undefined property values, you should either set them to "" or null because a value of undefined is not considered proper JSON format.

With this said, as a previous poster has expressed, if you find that you're initializing stuff with null or undefined more than once in a blue moon, then maybe you should reconsider how you go about coding your app.

晚风撩人 2024-11-25 23:16:56

您可以采用此处建议的约定,但确实没有充分的理由这样做。它的使用不够一致,没有意义。

为了使约定有用,您首先必须知道被调用的函数遵循约定。然后您必须显式测试返回值并决定要做什么。如果您得到未定义,您可以假设发生了被调用函数知道的某种错误。但是,如果发生错误,并且函数知道它,并且将其发送到更广泛的环境中很有用,为什么不使用错误对象呢?即抛出错误?

因此,归根结底,除了简单环境中的非常小的程序之外,该约定实际上毫无用处。

You might adopt the convention suggested here, but there really is no good reason to. It is not used consistently enough to be meaningful.

In order to make the convention useful, you first must know that the called function follows the convention. Then you have to explicitly test the returned value and decide what to do. If you get undefined, you can assume that some kind of error occurred that the called function knew about. But if an error happened, and the function knew about it, and it is useful to send that out into the wider environment, why not use an error object? i.e. throw an error?

So at the end of the day, the convention is practically useless in anything other than very small programs in simple environments.

榆西 2024-11-25 23:16:56

有些人说可以将对象初始化为null。我只是想指出解构参数默认值不适用于 null。例如:

const test = ({ name } = {}) => {
  console.log(name)
}

test() // logs undefined
test(null) // throws error

这需要在调用函数之前执行null检查,这可能经常发生。

A few have said that it is ok to initialise objects to null. I just wanted to point out that destructuring argument defaults don't work with null. For example:

const test = ({ name } = {}) => {
  console.log(name)
}

test() // logs undefined
test(null) // throws error

This requires performing null checks prior to calling the function which may happen often.

凉风有信 2024-11-25 23:16:56

null 中的一个有用属性,undefined 不符合条件:

> null + 3
3
> undefined + 3
NaN

当我想“关闭”数值时,我使用 null
或初始化一些。我最后一次使用是操作 css 转换:

const transforms = { perspective : null, rotateX : null };
// if already set, increase, if not, set to x
runTimeFunction((x) => { trasforms.perspective += x; });
// still useful, as setting perspective to 0 is different than turning it off
runTimeFunction2((x) => { transforms.perspective = null; });

// toCss will check for 'null' values and not set then at all
runTimeFunction3(() => { el.style.transform = toCss(transforms); });

不确定我是否应该使用这个属性……

A useful property in null that undefined does not qualifies:

> null + 3
3
> undefined + 3
NaN

I use null when I want to 'turn off' a numeric value,
or to initialize some. My last use was manipulating css transform:

const transforms = { perspective : null, rotateX : null };
// if already set, increase, if not, set to x
runTimeFunction((x) => { trasforms.perspective += x; });
// still useful, as setting perspective to 0 is different than turning it off
runTimeFunction2((x) => { transforms.perspective = null; });

// toCss will check for 'null' values and not set then at all
runTimeFunction3(() => { el.style.transform = toCss(transforms); });

Not sure if I should use this property thought...

那片花海 2024-11-25 23:16:56

未知变量:未定义

已知变量但没有值:null

  1. 您从服务器接收一个对象,server_object
  2. 您引用server_object.errj。它告诉您它是未定义。这意味着它不知道那是什么。
  3. 现在您引用server_object.err。它告诉您它是null。这意味着您引用了一个正确的变量,但它是空的;因此没有错误。

问题是,当你声明一个没有值的变量名(var hello)时,js 会将其声明为 undefined:该变量不存在;而程序员的意思主要是:“我还没有给它赋值”,即 null 的定义。

因此,程序员的默认行为——将没有值的变量声明为空——与 js 不一致——将其声明为不存在。此外,!undefined!null 都是 true,因此大多数程序员将它们视为等效的。

当然,您可以确保始终执行 var hello = null 但大多数人不会乱扔代码,以确保在故意松散类型的语言中,当他们和 !< /code> 运算符将 undefinednull 视为等效。

Unknown variable: undefined.

Known variable yet no value: null.

  1. You receive an object from a server, server_object.
  2. You reference server_object.errj. It tells you it’s undefined. That means it doesn’t know what that is.
  3. Now you reference server_object.err. It tells you it’s null. That means you’re referencing a correct variable but it’s empty; therefore no error.

The problem is when you declare a variable name without a value (var hello) js declares that as undefined: this variable doesn’t exist; whereas programmers mostly mean: “I’ve not given it a value yet”, the definition of null.

So the default behavior of a programmer—declaring a variable without a value as nothing—is at odds with js—declaring it as not existing. And besides, !undefined and !null are both true so most programmers treat them as equivalent.

You could of course ensure you always do var hello = null but most won’t litter their code as such to ensure type sanity in a deliberately loosely-typed language, when they and the ! operator treat both undefined and null as equivalent.

假装不在乎 2024-11-25 23:16:56

根据我们最近遇到的一次损坏,下面的示例显示了为什么我更喜欢使用 undefined 而不是 null,除非有特定原因要这样做:

function myFunc(myArg) {
    if (typeof myArg === 'string') {
        console.log('a', myArg);
    } else if (typeof myArg === 'object') {
        console.log('b', myArg);
        if (myArg.id) {
           console.log('myArg has an id');
        } else {
           console.log('myArg has an id');
        }
    } else {
        console.log('no value');
    }
}

以下值将玩得很好:

'abc'
{}
undefined
{ id: 'xyz' }

另一方面,假设 nullundefined 在这里是等效的,这会破坏代码。原因是 nullobject 类型,而 undefinedundefined 类型。因此,这里的代码会中断,因为您无法测试 null 上的成员。

我见过大量具有类似外观的代码的情况,其中 null 只是自问问题:

if (typeof myvar === 'string') {
  console.log(myvar);
} else if (typeof myvar === 'object') {
  console.log(myvar.id);  
}

这里的修复方法是显式测试 null:

if (typeof myvar === 'string') {
  console.log(myvar);
} else if (myvar !== null && typeof myvar === 'object') {
  console.log(myvar.id);  
}

我的态度是针对 a 的弱点进行编码语言以及该语言程序员的典型行为,因此这里的哲学是默认使用“未定义”。

Based on a recent breakage we ran into, the example below shows why I prefer to use undefined over null, unless there is a specific reason to do otherwise:

function myFunc(myArg) {
    if (typeof myArg === 'string') {
        console.log('a', myArg);
    } else if (typeof myArg === 'object') {
        console.log('b', myArg);
        if (myArg.id) {
           console.log('myArg has an id');
        } else {
           console.log('myArg has an id');
        }
    } else {
        console.log('no value');
    }
}

The following values will play nicely:

'abc'
{}
undefined
{ id: 'xyz' }

On the other hand the assumption of null and undefined being equivalent here breaks the code. The reason being is that null is of type of object, where as undefined is of type undefined. So here the code breaks because you can't test for a member on null.

I have seen a large number of cases with code of similar appearance, where null is just asking for problems:

if (typeof myvar === 'string') {
  console.log(myvar);
} else if (typeof myvar === 'object') {
  console.log(myvar.id);  
}

The fix here would be to explicitly test for null:

if (typeof myvar === 'string') {
  console.log(myvar);
} else if (myvar !== null && typeof myvar === 'object') {
  console.log(myvar.id);  
}

My attitude is to code for the weaknesses of a language and the typical behaviours of programmers of that language, hence the philosophy here of going with 'undefined' bey default.

请叫√我孤独 2024-11-25 23:16:56

DOM 节点和元素不是未定义的,但可能为 null。

  • 元素的最后一个子元素的 nextSibling 为 null。

  • 第一个子级的 previousSibling 为 null。

  • 如果文档中不存在该元素,则 document.getElementById 引用为 null。

但在这些情况下,值都不是未定义;那里只是没有节点。

DOM nodes and elements are not undefined, but may be null.

  • The nextSibling of the last child of an element is null.

  • The previousSibling of the first child is null.

  • A document.getElementById reference is null if the element does not exist in the document.

But in none of these cases is the value undefined; there just is no node there.

偏爱自由 2024-11-25 23:16:56

在 JavaScript 中,值 null 表示故意不存在任何对象值。 null 表示缺乏标识,表示变量不指向任何对象。

全局 undefined 属性表示原始值 undefined
undefined 是自动分配给变量的原始值。
undefined 表示引用不存在。

In JavaScript, the value null represents the intentional absence of any object value. null expresses a lack of identification, indicating that a variable points to no object.

The global undefined property represents the primitive value undefined.
undefined is a primitive value automatically assigned to variables.
undefined is meant to say that the reference is not existing.

可是我不能没有你 2024-11-25 23:16:56

我完全不同意使用 null 或 undefined 是不必要的。
未定义是使整个原型链接过程保持活力的东西。
因此,仅使用 null 的编译器无法检查该属性是否等于 null,或者它是否未在端点原型中定义。在其他动态类型语言(例如Python)中,如果您想访问未定义的属性,它会抛出异常,但对于基于原型的语言,编译器还应该检查父原型,这是未定义最需要的地方。

使用 null 的全部意义只是将变量或属性与单例对象绑定,具有空的意义,并且使用 null 也有性能目的。这两个代码的执行时间不同。

var p1 = function(){this.value = 1};
var big_array = new Array(100000000).fill(1).map((x, index)=>{
    p = new p1();
    if(index > 50000000){
       p.x = "some_string";
    }

    return p;
});
big_array.reduce((sum, p)=> sum + p.value, 0)

var p2 = function(){this.value = 1, p.x = null};
var big_array = new Array(100000000).fill(1).map((x, index)=>{
    p = new p2();
    if(index > 50000000){
       p.x = "some_string";
    }

    return p; 
});
big_array.reduce((sum, p)=> sum + p.value, 0)

I completely disagree that usage null or undefined is unnecessary.
undefined is thing which keeping alive whole prototype chaining process.
So compiler only with null can't check if this property just equal to null, or its not defined in endpoint prototype. In other dynamic typed languages(f.e. Python) it throws exception if you want access to not defined property, but for prototype-based languages compiler should also check parent prototypes and here are the place when undefined need most.

Whole meaning of using null is just bind variable or property with object which is singleton and have meaning of emptiness,and also null usage have performance purposes. This 2 code have difference execution time.

var p1 = function(){this.value = 1};
var big_array = new Array(100000000).fill(1).map((x, index)=>{
    p = new p1();
    if(index > 50000000){
       p.x = "some_string";
    }

    return p;
});
big_array.reduce((sum, p)=> sum + p.value, 0)

var p2 = function(){this.value = 1, p.x = null};
var big_array = new Array(100000000).fill(1).map((x, index)=>{
    p = new p2();
    if(index > 50000000){
       p.x = "some_string";
    }

    return p; 
});
big_array.reduce((sum, p)=> sum + p.value, 0)
心房敞 2024-11-25 23:16:56

我现在正在解决这个确切的问题,并考虑以下理念:

  1. 任何旨在返回结果的函数如果找不到结果都应返回 null
  2. 任何不打算返回结果的函数都会隐式返回 undefined 。

对我来说,这个问题很重要,因为任何调用返回结果的函数的人都不应该对是否测试未定义与空值有任何疑问。

这个答案并不试图解决:

  1. null 与未定义的属性值
  2. 函数中的变量为 null 与未定义

在我看来,变量是你自己的事,而不是 API 的一部分,任何 OO 系统中的属性都是定义的,因此应该定义的值与未定义时的值不同(已定义为 null,未定义是访问对象中不存在的内容时得到的值)。

I'm working through this exact question right now, and looking at the following philosophy:

  1. Any function that is intended to return a result should return null if it fails to find a result
  2. Any function that is NOT intended to return a result implicitly returns undefined.

For me, this question is significant because anyone calling a function that returns a result should have no question as to whether to test for undefined vs null.

This answer does not attempt to address:

  1. Property values of null vs undefined
  2. Variables within your functions being null vs undefined

In my opinion, variables are your own business and not a part of your API, and properties in any OO system are defined and therefore should be defined with value different from what they would be if not defined (null for defined, undefined is what you get when accessing something that is not in your object).

沫雨熙 2024-11-25 23:16:56

原因如下:var undefined = 1 是合法的 javascript,但 var null = 1 是语法错误。不同之处在于 null 是语言关键字,而 undefined 由于某种原因不是。

如果您的代码依赖于与 undefined 的比较,就好像它是一个关键字(if (foo == undefined) - 这是一个很容易犯的错误),它只能工作,因为没有人拥有定义了一个具有该名称的变量。所有这些代码都容易受到意外或恶意定义具有该名称的全局变量的攻击。当然,我们都知道在 javascript 中意外定义全局变量是完全不可能的......

Here's a reason: var undefined = 1 is legal javascript, but var null = 1 is a syntax error. The difference is that null is a language keyword, while undefined is, for some reason, not.

If your code relies on comparisons to undefined as if it's a keyword (if (foo == undefined) -- a very easy mistake to make) that only works because nobody has defined a variable with that name. All that code is vulnerable to someone accidentally or maliciously defining a global variable with that name. Of course, we all know that accidentally defining a global variable is totally impossible in javascript...

旧夏天 2024-11-25 23:16:56

只是想补充一点,使用某些 javascript 库时, null 和 undefined 可能会产生意想不到的后果。

例如,lodash 的 get 函数,它接受默认值作为第三个参数:

const user = {
  address: {
    block: null,
    unit: undefined,
  }
}
console.log(_.get(user, 'address.block', 'Default Value')) // prints null
console.log(_.get(user, 'address.unit', 'Default Value')) // prints 'Default Value'
console.log(_.get(user, 'address.postalCode', 'Default Value')) // prints 'Default Value'

另一个例子:如果在 React 中使用 defaultProps,如果属性传递为 null,则默认 props不使用,因为 null 被解释为定义的值
例如

class MyComponent extends React.Component {
   static defaultProps = {
      callback: () => {console.log('COMPONENT MOUNTED')},
   }
   componentDidMount() {
      this.props.callback();
   }
}
//in some other component
<MyComponent />   // Console WILL print "COMPONENT MOUNTED"
<MyComponent callback={null}/>   // Console will NOT print "COMPONENT MOUNTED"
<MyComponent callback={undefined}/>   // Console WILL print "COMPONENT MOUNTED"

Just wanna add that with usage of certain javascript libraries, null and undefined can have unintended consequences.

For example, lodash's get function, which accepts a default value as a 3rd argument:

const user = {
  address: {
    block: null,
    unit: undefined,
  }
}
console.log(_.get(user, 'address.block', 'Default Value')) // prints null
console.log(_.get(user, 'address.unit', 'Default Value')) // prints 'Default Value'
console.log(_.get(user, 'address.postalCode', 'Default Value')) // prints 'Default Value'

Another example: If you use defaultProps in React, if a property is passed null, default props are not used because null is interpreted as a defined value.
e.g.

class MyComponent extends React.Component {
   static defaultProps = {
      callback: () => {console.log('COMPONENT MOUNTED')},
   }
   componentDidMount() {
      this.props.callback();
   }
}
//in some other component
<MyComponent />   // Console WILL print "COMPONENT MOUNTED"
<MyComponent callback={null}/>   // Console will NOT print "COMPONENT MOUNTED"
<MyComponent callback={undefined}/>   // Console WILL print "COMPONENT MOUNTED"
岛歌少女 2024-11-25 23:16:56

这里已经有一些很好的答案,但不是我正在寻找的答案。 nullundefined 两者“技术上”都在虚假方面做了同样的事情,但是当我通读代码并看到“null”时,我期望它是用户定义的空值,某些内容被显式设置为不包含任何值,如果我通读代码并看到“未定义”,那么我假设它是从未被任何东西初始化或分配的代码。通过这种方式,代码可以告诉您某些事情是由未初始化的内容还是空值引起的。因此,您确实不应该手动将“未定义”分配给某些内容,否则它会扰乱您(或其他开发人员)读取代码的方式。如果其他开发人员看到“未定义”,他们不会直观地假设是您使其未定义,他们会假设它尚未初始化,而实际上它已初始化。对我来说,这是最重要的,当我阅读代码时,我想看看它告诉我什么,我不想猜测并弄清楚东西是否“实际上”已经初始化。

更不用说在打字稿中使用它们意味着两件不同的事情。 using:

interface Example {
    name?: string
}

表示name可以是未定义的,也可以是字符串,但不能为空。如果你想要它为空,你必须显式使用:

interface Example {
  name: string | null
}

即使这样你也将被迫至少用“null”来初始化它。

当然,只有当您在 tsconfig.json 中使用 "strictNullChecks": true 时,这才是正确的。

There are already some good answers here but not the one that I was looking for. null and undefined both "technically" do the same thing in terms of both being falsy, but when I read through code and I see a "null" then I'm expecting that it's a user defined null, something was explicitly set to contain no value, if I read through code and see "undefined" then I assume that it's code that was never initialized or assigned by anything. In this way code can communicate to you whether something was caused by uninitialized stuff or null values. Because of that you really shouldn't assign "undefined" manually to something otherwise it messes with the way you (or another developer) can read code. If another developer sees "undefined" they're not going to intuitively assume it's you who made it undefined, they're going to assume it's not been initialized when in fact it was. For me this is the biggest deal, when I read code I want to see what it's telling me, I don't want to guess and figure out if stuff has "actually" been initialized.

Not even to mention that using them in typescript means two different things. Using:

interface Example {
    name?: string
}

Means that name can be undefined or a string, but it can't be null. If you want it null you have to explicitly use:

interface Example {
  name: string | null
}

And even then you'll be forced to initialize it at least with "null".

That's of course only true if you're using "strictNullChecks": true in tsconfig.json.

倾听心声的旋律 2024-11-25 23:16:56

请注意,如果序列化(例如使用 JSON.stringify),undefined 将被删除,并且如果使用 console.log,也不可见。但如果您使用 Object.keys 进行调试,它仍然存在:

let obj = {nuller: null, undef: undefined}
console.log(obj)
console.log(JSON.stringify(obj))
console.log(JSON.parse(JSON.stringify(obj))
console.log(Object.keys(obj))

即使使用 URLSearchParams 之类的东西,

console.log((new URLSearchParams(obj)).toString());

也会打印出 nuller=null&undef=undefined

Please note that undefined will be erased if serializing, e.g. with JSON.stringify and is also not visible if using console.log. But it is still there if you debug with Object.keys:

let obj = {nuller: null, undef: undefined}
console.log(obj)
console.log(JSON.stringify(obj))
console.log(JSON.parse(JSON.stringify(obj))
console.log(Object.keys(obj))

And even there if using such things as URLSearchParams

console.log((new URLSearchParams(obj)).toString());

This will print out nuller=null&undef=undefined.

你是年少的欢喜 2024-11-25 23:16:56

要编写简单的代码,您需要降低复杂性和变化。当对象上的变量或属性没有值时,它是未定义的,并且要为 null 值,您需要为其分配 null 值。

To write simple code you need to keep complexity and variation down. When a variable or a property on an object does not have a value it is undefined , and for a value to be null you need to assign it a null value.

带刺的爱情 2024-11-25 23:16:56

未声明与 Null

null 既是一个 Object“类型”,也是 7 种独特的原始值类型之一,称为 null

undefined 既是名为 undefined 的全局范围属性和类型,又是名为 undefined 的 7 种独特原始值类型之一(窗口.未定义) 。

我们感兴趣的是用作值的原始类型

对于null,作为值类型,它意味着已将空值分配给变量,但变量类型(数字、字符串等)仍然被定义。它只是没有价值。这就是 null 的意思。这意味着变量具有空值,但它仍然是一个值。它还使用某种值重新初始化变量,但不是未定义作为类型。

undefined 是一种特殊情况。当您声明变量(或使用尚未声明的缺失值)时,它的类型为类型 未定义,因为浏览器不知道已为其分配了什么类型的数据然而。如果声明了变量但未分配值,则在分配值之前默认会分配原始值 undefined,这意味着该变量不存在或存在但未分配值。

null 一样,undefined 也是一种原始值类型。但与 null 不同的是,它表示该变量不存在,其中 null 表示该值不存在。这就是为什么在检查值是否为 null 或空之前,最好先检查变量是否存在以及是否已使用 undefined 为变量分配了变量。 undefined 意味着编译中根本不存在变量或对象。该变量要么尚未声明,要么声明时缺少值,因此未初始化。因此,检查 undefined 是避免 JavaScript 中多种类型错误的好方法,并取代 null

这就是为什么我不会依赖 nullundefined 进行真/假检查,即使它们都会返回错误响应,如 undefined 意味着缺少特征、对象或变量的额外步骤,而不仅仅是真/假检查。它意味着更多的东西。如果缺少未声明的变量,真实的语句将触发错误!

让我们先看看未定义

        //var check1;// variable doesnt even exist so not assigned to "undefined"
        var check2;// variable declared but not initialized so assigned "undefined"
        var check3 = 'hello world';// variable has a value so not undefined

        console.log('What is undefined?');

        //console.log(check1 === undefined);// ERROR! check1 does not exist yet so not assigned undefined!
        console.log(check2 === undefined);// True
        console.log(check3 === undefined);// False
        console.log(typeof check1 === 'undefined');// True - stops the ERROR!
        console.log(typeof check2 === 'undefined');// True
        console.log(typeof check3 === 'undefined');// False

正如您所看到的未声明变量,或者已声明但未初始化,两者都已赋值一种未定义的类型。请注意,未初始化的已声明变量会被分配一个未定义值,这是原始值类型,但不存在的变量是未定义类型

null 与缺失变量或尚未赋值的变量无关,因为 null 仍然是一个值。因此,任何带有 null 的内容都已声明初始化。另请注意,分配了 null 值的变量实际上是 object 类型,与未定义类型不同。例如...

        var check4 = null;
        var check5 = 'hello world';

        console.log('What is null?');

        console.log(check4 === undefined);// False
        console.log(check5 === undefined);// False
        console.log(typeof check4 === 'undefined');// False
        console.log(typeof check5 === 'undefined');// False
        console.log(typeof check4);// return 'object'
        console.log(typeof check5);// return 'string'

正如您所看到的,每个变量的行为都不同,但两者都是原始值,您可以分配任何变量。只要理解它们代表变量和对象的不同状态即可。

Undeclared vs Null

null is both an Object "type" and one of the 7 unique primitive value types called null

undefined is both a global scope property and type called undefined and one of the 7 unique primitive value types called undefined (window.undefined) .

It is the primitive types we use as values we are interested in.

In the case of null, as a value type it means an empty value has been assigned to a variable, but the variable type (Number, String, etc) is still defined. It just has no value. That is what null means. It means a variable has an empty value but it is still a value. It also reinitializes the variable with some kind of value, but is not undefined as a type.

undefined is a special case. When you declare a variable (or use a missing value not yet declared) it is of type undefined, as the browser does not know what type of data has been assigned to it yet. If the variable is declared but not assigned a value is is assigned the primitive calue undefined by default prior to assigning a value, and implies the variable does not exist or exists but has no value assigned.

Like null, undefined is also a primitive value type. But unlike null it means the variable does not exist, where null means the value does not exist. That is why its always better to check if the variable exists and has been assigned a variable using undefined before checking if the value is null or empty. undefined implies no variable or object exists in the compilation at all. The variable has either not been declared or declared with a missing value so not initialized. So checking for undefined is a very good way to avoid many types of errors in JavaScript and supersedes null.

That is why I would not rely on "truthy" checks for true/false with null and undefined, even though they will both return a false response, as undefined implies an additional step for missing feature, object, or variable, not just a true/false check. It implies something more. If you have a missing undeclared variable, truthy statements will trigger an ERROR!

Let's look at undefined first:

        //var check1;// variable doesnt even exist so not assigned to "undefined"
        var check2;// variable declared but not initialized so assigned "undefined"
        var check3 = 'hello world';// variable has a value so not undefined

        console.log('What is undefined?');

        //console.log(check1 === undefined);// ERROR! check1 does not exist yet so not assigned undefined!
        console.log(check2 === undefined);// True
        console.log(check3 === undefined);// False
        console.log(typeof check1 === 'undefined');// True - stops the ERROR!
        console.log(typeof check2 === 'undefined');// True
        console.log(typeof check3 === 'undefined');// False

As you can see undeclared variables, or declared but not initialized, both are assigned a type of undefined. Notice declared variables that are not initialized are assigned a value of undefined, the primitive value type but variables that do not exist are undefined types.

null has nothing to do with missing variables or variables not yet assigned values, as null is still a value. So anything with a null is already declared and initialized. Also notice a variable assigned a null value is actually an object type unlike undefined types. For example...

        var check4 = null;
        var check5 = 'hello world';

        console.log('What is null?');

        console.log(check4 === undefined);// False
        console.log(check5 === undefined);// False
        console.log(typeof check4 === 'undefined');// False
        console.log(typeof check5 === 'undefined');// False
        console.log(typeof check4);// return 'object'
        console.log(typeof check5);// return 'string'

As you can see each act differently and yet both are primitive values you can assign any variable. Just understand they represent different states of variables and objects.

じ违心 2024-11-25 23:16:56

nullundefined 之间存在重大差异。如果使用不当,可能会造成严重后果。在我的示例中,所有者检查产品是否属于所有者或根本没有产品(例如在数据库中)。使用<代码>|| Product === null 即使还没有产品记录,您仍然可以访问产品列表。相比之下,使用 || Product === undefined 是不可能的

import Product from '../../../models/Product.js';

const checkOwner = async (req) => {
  try {
    const product = await Product.findOne({
      user: req.user.id,
    });
    if (product || product === null) {
      console.log(product ); // print the product OR null
      return true;
    } else {
      return false;
    }
  } catch (error) {
    console.log(error);
    return 'error';
  }
};

export default checkOwner;

顺便说一句:

null == undefined 评估 true 因为它们是松散相等的。

null === undefined 计算 false 因为它们相等

There are major differences between null and undefined. If it is used incorrectly, that can have serious consequences. In my example, the owner checks if the product own to the owner or there are no products at all (e.g. in database). With || product === null you can still access the product list even if there is no product record yet. In comparison, with || product === undefined will be not possible

import Product from '../../../models/Product.js';

const checkOwner = async (req) => {
  try {
    const product = await Product.findOne({
      user: req.user.id,
    });
    if (product || product === null) {
      console.log(product ); // print the product OR null
      return true;
    } else {
      return false;
    }
  } catch (error) {
    console.log(error);
    return 'error';
  }
};

export default checkOwner;

And by the way:

null == undefined evaluates true because they are loosely equal.

null === undefined evaluates false because they are NOT equal

星軌x 2024-11-25 23:16:56

Null 是一个具有空/空白或没有值的对象,请注意,null 与零不同,因为零的值为 0;

//null
var d = null;
console.log(d);

上面的代码 null 表示故意不存在任何值,通常用于指示变量没有值或已被显式设置为 null。将 null 分配给变量表示该变量已声明并初始化,但当前不包含任何值。尽管如此,未来仍可预期价值。

//undefine
var d; 
console.log(d);

undefined 是否是变量的初始默认值。
上面的代码显示变量已被声明但尚未初始化。

Null is an object having empty/blank or no value note that null is different than zero because zero has its value is 0;

//null
var d = null;
console.log(d);

Above code null represents the intentional absence of any value and is often used to indicate that a variable has no value or has been explicitly set to null. Assign null to a variable to denote that the variable is declared and initialized and currently doesn't hold a value. Still, a value can be expected in the future.

//undefine
var d; 
console.log(d);

whether undefined is the initial default value of variables.
The above code shows variable has been declared but not initialized.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文