原文作者:Dmitri Pavlutin
译者:Gopal
JavaScript 有两种类型:原始类型(strings, booleans, numbers, symbols)和对象
对象是一个复杂的数据结构。最简单的 JavaScript 对象是普通对象 —— 键和相关值的集合
let myObject = {
name: 'Eric Cartman'
};
但是很多情况下不能创建一个对象。在这种情况下,JavaScript 提供了一个特殊的值 null —— 表示缺少对象
let myObject = null;
在这篇文章中,你将学习关于 JavaScript 中的 null 的一切: 它的含义,如何检测它,null 和 undefined 之间的区别,以及为什么大量使用 null 会造成代码维护困难等
JavaScript 规范中这么描述 null
null 是一种原始类型,表示有意不包含任何对象值
如果您看到 null(分配给变量或由函数返回),那么在那个位置原本应该是一个对象,但由于某种原因,一个对象没有创建
比如,函数 greetObject() 创建对象,但也可以在无法创建对象时返回 null:
function greetObject(who) {
if (!who) {
return null;
}
return { message: `Hello, ${who}!` };
}
greetObject('Eric'); // => { message: 'Hello, Eric!' }
greetObject(); // => null
当上面的函数中传入一个字符串参数时,如预期的,函数返回一个对象 { message: 'Hello, Eric!' }
但是,函数中不传任何参数时,该函数返回 null。返回 null 是合理的,因为 who 参数没有值,导致 greeting 对象无法创建
考虑关于 null 的一个比较贴切的比喻,你可以把变量想象成一个盒子。就像变量可以容纳对象一样,盒子也可以容纳像茶壶等的物品
但一旦你收到一个盒子,打开它,什么也没有!有人弄错了,给了你一个空盒子。该盒子不包含任何内容,或者换句话说,它包含一个 null 值
检查 null 好方法是使用严格相等运算符
const missingObject = null;
const existingObject = { message: 'Hello!' };
missingObject === null; // => true
existingObject === null; // => false
missingObject === null 的结果为 true,因为 missingObject 变量包含一个 null 值。如果变量包含非空值,比如对象,则表达式 existingObject === null 的结果为 false
null 与 false、0、"、undefined、NaN 都是假值。如果在条件语句中遇到它们,那么 JavaScript 将把它们强制为 false
Boolean(null); // => false
if (null) {
console.log('null is truthy');
} else {
console.log('null is falsy'); // logs 'null is falsy'
}
typeof value 类型操作符可以确定值的类型。例如,类型为 15 的是 number,typeof { prop: 'Value' } 等于 object。
有趣的是,null 值类型的结果是什么
typeof null; // => 'object'
一个缺失的对象类型怎么被判断为 object? 原来 typoef null 作为 object 是早期 JavaScript 实现中的一个错误
不要使用 typeof 操作符检测 null 值。如前所述,使用严格的相等运算符 myVar === null
如果你想使用 typeof 去检查一个变量是否是一个对象,你必须排除掉 null 的情况
function isObject(object) {
return typeof object === 'object' && object !== null;
}
isObject({ prop: 'Value' }); // => true
isObject(15); // => false
isObject(null); // => false
null 通常会在你希望使用对象的情况下意外出现。然后,如果尝试从 null 中提取属性,JavaScript 会抛出一个错误
让我们再次使用 greetObject() 函数并尝试从返回的对象中访问 message 属性
let who = '';
greetObject(who).message;
// throws "TypeError: greetObject() is null"
因为 who 变量是一个空字符串,所以函数返回 null。当从 null 访问 message 属性时,将抛出类型错误错误
你可以通过使用 可选链操作符 来处理 null
let who = '';
greetObject(who)?.message ?? 'Hello, Stranger!';
// => 'Hello, Stranger!'
或者使用下一节中描述的两种选择。
当你不能构造一个对象时,很容易返回 null。但这种做法也有缺点
一旦 null 出现在执行堆栈中,你总是必须检查它
我们尽量避免返回 null:
nullnull让我们回忆一下 greetObject() 函数返回 greeting 对象
当缺少参数时,可以返回一个默认对象,而不是返回 null
function greetObject(who) {
if (!who) {
who = 'Stranger';
}
return { message: `Hello, ${who}!` };
}
greetObject('Eric'); // => { message: 'Hello, Eric!' }
greetObject(); // => { message: 'Hello, Stranger!' }
或者抛出一个错误
function greetObject(who) {
if (!who) {
throw new Error('"who" argument is missing');
}
return { message: `Hello, ${who}!` };
}
greetObject('Eric'); // => { message: 'Hello, Eric!' }
greetObject(); // => throws an error
这些实践可以让你完全避免处理 null
undefined 就是未初始化的变量或对象属性的值
例如,如果在声明变量时没有赋初值,那么访问该变量的结果为 undefined
let myVariable;
myVariable; // => undefined
null 和 undefined 之间的主要区别是,null 表示丢失了的对象,而 undefined 表示未初始化的状态
严格相等运算符 === 区分 null 和 undefined
null === undefined; // => false
而松散相等运算符 == 则认为 null 和 undefined 相等
null == undefined; // => true
我使用松散相等运算符检查变量是否为 null 或 undefined
function isEmpty(value) {
return value == null;
}
isEmpty(42); // => false
isEmpty({ prop: 'Value' }); // => false
isEmpty(null); // => true
isEmpty(undefined); // => true
null 是 JavaScript 中的一个特殊值,表示丢失的对象
严格相等运算符判断变量是否为空: variable === null。
typoef 操作符用于确定变量的类型(number, string, boolean)。但是,typeof 在 null 情况下会引起误解: typeof null 结果为 object
null 和 undefined 在某种程度上是等价的,但null 表示一个丢失的对象,而 undefined 表示未初始化状态
尽可能避免返回 null 或将变量设置为 null。因为这种做法会导致 null 值的扩展和需要对 null 的验证。相反,尝试使用具有默认属性的对象,或者甚至抛出错误会是更好的实践
你会使用什么方法来检查 null?
我在破坏脚本的字符串中出现了一些奇怪的字符。据我所知,通过putbadstring到控制台,它们是"\0\0\0\0"。我想对此进行测试,以便我可以忽略它们...但是如何呢?以为这就是blank?和empty?的用途?!?:>badstring="\0"=>"\u0000">badstring.blank?NoMethodError:undefinedmethod`blank?'for"\u0000":Stringfrom(irb):97from/Users/meltemi/.rvm/rubies/ruby-2.0.0-p195/bin/irb:16:in`'>badstring.em
我遇到了一个非常奇怪的问题,我很难解决。在我看来,我有一个与data-remote="true"和data-method="delete"的链接。当我单击该链接时,我可以看到对我的Rails服务器的DELETE请求。返回的JS代码会更改此链接的属性,其中包括href和data-method。再次单击此链接后,我的服务器收到了对新href的请求,但使用的是旧的data-method,即使我已将其从DELETE到POST(它仍然发送一个DELETE请求)。但是,如果我刷新页面,HTML与"new"HTML相同(随返回的JS发生变化),但它实际上发送了正确的请求类型。这就是这个问题令我困惑的
我在我的rails应用程序中安装了来自github.com的acts_as_versioned插件,但有一段代码我不完全理解,我希望有人能帮我解决这个问题class_eval我知道block内的方法(或任何它是什么)被定义为类内的实例方法,但我在插件的任何地方都找不到定义为常量的CLASS_METHODS,而且我也不确定是什么here,并且有问题的代码从lib/acts_as_versioned.rb的第199行开始。如果有人愿意告诉我这里的内幕,我将不胜感激。谢谢-C 最佳答案 这是一个异端。http://en.wikipedia
按照目前的情况,这个问题不适合我们的问答形式。我们希望答案得到事实、引用或专业知识的支持,但这个问题可能会引发辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visitthehelpcenter指导。关闭9年前。我最近开始学习Ruby,这是我的第一门编程语言。我对语法感到满意,并且我已经完成了许多只教授相同基础知识的教程。我已经写了一些小程序(包括我自己的数组排序方法,在有人告诉我谷歌“冒泡排序”之前我认为它非常聪明),但我觉得我需要尝试更大更难的东西来理解更多关于Ruby.关于如何执行此操作的任何想法?
我有这个:AccountSummary我想单击该链接,但在使用link_to时出现错误。我试过:bot.click(page.link_with(:href=>/menu_home/))bot.click(page.link_with(:class=>'top_level_active'))bot.click(page.link_with(:href=>/AccountSummary/))我得到的错误是:NoMethodError:nil:NilClass的未定义方法“[]” 最佳答案 那是一个javascript链接。Mechan
我在Ruby中遇到了一个关于Dir[]和File.join()的简单程序,blobs_dir='/path/to/dir'Dir[File.join(blobs_dir,"**","*")].eachdo|file|FileUtils.rm_rf(file)ifFile.symlink?(file)我有两个困惑:首先,File.join(@blobs_dir,"**","*")中的第二个和第三个参数是什么意思?其次,Dir[]在Ruby中有什么用?我只知道它等价于Dir.glob(),但是,我对Dir.glob()确实不是很清楚。 最佳答案
这个问题在这里已经有了答案:Rubymetaclassconfusion(4个答案)关闭7年前。我对Ruby对象模型不太了解。首先,Ruby中的一切都是Class的实例吗??这些都产生true:pObject.instance_of?(Class)pClass.instance_of?(Class)pModule.instance_of?(Class)pBasicObject.instance_of?(Class)classHello;endpHello.instance_of?(Class)我不太明白这怎么可能,如果Object是Class的父类(superclass),它怎么可能都
1.回顾.TransportServicepublicclassTransportServiceextendsAbstractLifecycleComponentTransportService:方法:1publicfinalTextendsTransportResponse>voidsendRequest(finalTransport.Connectionconnection,finalStringaction,finalTransportRequestrequest,finalTransportRequestOptionsoptions,TransportResponseHandlerT>
目录一.大致如下常见问题:(1)找不到程序所依赖的Qt库version`Qt_5'notfound(requiredby(2)CouldnotLoadtheQtplatformplugin"xcb"in""eventhoughitwasfound(3)打包到在不同的linux系统下,或者打包到高版本的相同系统下,运行程序时,直接提示段错误即segmentationfault,或者Illegalinstruction(coredumped)非法指令(4)ldd应用程序或者库,查看运行所依赖的库时,直接报段错误二.问题逐个分析,得出解决方法:(1)找不到程序所依赖的Qt库version`Qt_5'
我看到有关未找到文件min.map的错误消息:GETjQuery'sjquery-1.10.2.min.mapistriggeringa404(NotFound)截图这是从哪里来的? 最佳答案 如果ChromeDevTools报告.map文件的404(可能是jquery-1.10.2.min.map、jquery.min.map或jquery-2.0.3.min.map,但任何事情都可能发生)首先要知道的是,这仅在使用DevTools时才会请求。您的用户不会遇到此404。现在您可以修复此问题或禁用sourcemap功能。修复:获取文