JS中的每个值/对象都有构造函数吗?

时间:2017-01-08 23:51:19

标签: javascript node.js

编写库并最终确定目标是确定对象是否是可观察对象。但是,我不确定用户是否会传递非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));

};

4 个答案:

答案 0 :(得分:3)

undefinednull没有constructor属性。

数字之类的值似乎有constructor,但实际上有些“特殊”,因为

x = 3
x.y = "z"         // no problem
console.log(x.y)  // undefined!

“包裹”数字(x = new Number(42))是普通对象,您可以在其中存储其他属性。因此,虽然3Number声明为其构造函数,但调用它并不会生成与数字3相同类型的值。

答案 1 :(得分:1)

除了' null' &安培; '未定义'原语,所有其他原语都有构造函数属性。

答案 2 :(得分:1)

.constructor属性用于您正在尝试的内容是一个坏主意,因为这消除了子类化的任何本质,并消除了调用者使用支持所需合同的自己的observable风格的能力,但没有命名你想要的。它还删除了使用mixins或复合对象的能力,其中原始构造函数本身不是可观察对象。这些可能不是你想要禁止的东西。

现在您已经修改了问题以显示您真正要做的事情(检测您是否正在传递可观察对象),您有几个选择:

  1. 测试instanceof以查看它是否来自已知的基础对象。
  2. 测试对象,看它是否具有行为符合您想要的对象的已知和预期属性。这称为"duck" typing。如果它像鸭子一样嘎嘎叫,它就必须是一只鸭子,即使你还没有检查它的DNA,它就足以成为你想要做的事情。
  3. 我建议你扩展你的成就:

    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