编写库并最终确定目标是确定对象是否是可观察对象。但是,我不确定用户是否会传递非Observable值。
我很惊讶JS中的原语甚至都有构造函数属性,例如:
const bool = true;
console.log(bool.constructor.name);
const string = 'foo';
console.log(string.constructor.name);
const num = 5;
console.log(num.constructor.name);
所有已定义的,让我感到惊讶的是,我会猜到JS中的原始值不会有构造函数(出于性能原因,例如在Java中)。
所以我的问题是:JS中是否存在构造函数未定义的任何值?
最终,我希望创建一个体面的测试,一个值是一个Observable,这是我的初步测试:
module.exports = function isObservable(val) {
return (val && typeof val.subscribe === 'function'
&& val.constructor && /Observable/.test(val.constructor.name));
};
答案 0 :(得分:3)
undefined
和null
没有constructor
属性。
数字之类的值似乎有constructor
,但实际上有些“特殊”,因为
x = 3
x.y = "z" // no problem
console.log(x.y) // undefined!
“包裹”数字(x = new Number(42)
)是普通对象,您可以在其中存储其他属性。因此,虽然3
将Number
声明为其构造函数,但调用它并不会生成与数字3
相同类型的值。
答案 1 :(得分:1)
除了' null' &安培; '未定义'原语,所有其他原语都有构造函数属性。
答案 2 :(得分:1)
将.constructor
属性用于您正在尝试的内容是一个坏主意,因为这消除了子类化的任何本质,并消除了调用者使用支持所需合同的自己的observable风格的能力,但没有命名你想要的。它还删除了使用mixins或复合对象的能力,其中原始构造函数本身不是可观察对象。这些可能不是你想要禁止的东西。
现在您已经修改了问题以显示您真正要做的事情(检测您是否正在传递可观察对象),您有几个选择:
instanceof
以查看它是否来自已知的基础对象。我建议你扩展你的成就:
return (val &&
typeof val.subscribe === 'function' &&
typeof val.unsubscribe === 'function')
添加一些您期望在合法可观察对象上的属性/方法。您可以根据需要进行严格的测试(如果您想要测试10种不同的方法,甚至可以调用几种没有副作用的方法,看看它们是否返回了所需的值),但实际上,您可能只是想确定它有点闻起来像是一个可观察的,然后如果打电话给你一半半观察,这就是他们的问题。机会是你真正的目标,就是当他们犯了一个编程错误时建议开发人员,这样你就可以“早期”在开发过程中抛出异常,表明他们已经传递了错误的对象。最简单的气味测试应该足够了。你通常对测试子问题不感兴趣。
没有理由测试更多属性而不是实际使用。如果有人想制作一个支持你使用的属性的自己的observable版本,那么他们应该被允许这样做,所以你不必担心。如果他们试图使用看起来像一个可观察对象的东西,但是没有完全实现对象上的正确接口,那么那就是它们不会给你一个合法的可观察对象,而不是你的API。
答案 3 :(得分:1)
JS中的每个值/对象都有构造函数吗?
简单的答案是“NO”,因为我们知道null和undefined不会“拥有”构造函数。所以有些值“没有构造函数”
更合格的答案是“我们不知道null是否有构造函数,因为如果你试图执行:”让a = null.constructor “你的程序崩溃。
但是在你的评论中你会说“我特别想知道是否存在构造函数未定义的情况”。这也是我的问题。
换句话说,是否存在我们可以执行的情况 a.constructor === undefined 并得到结果?
该问题的答案是“是”,如此代码段所示:
let a = {};
a.constructor = undefined;
console.log (a.constructor);
// -> console shows: undefined