Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/427.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript JS中的每个值/对象都有构造函数吗?_Javascript_Node.js - Fatal编程技术网

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

Javascript JS中的每个值/对象都有构造函数吗?,javascript,node.js,Javascript,Node.js,编写一个库,最终目标是确定一个对象是否是可观察的。但是,我不确定用户是否会传递一个不可见的值 我很惊讶,即使是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中的原语也有构造函数属性,例如:

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中是否有构造函数未定义的值

最终,我希望创建一个体面的测试,证明一个值是可观察的,以下是我的初步测试:

module.exports = function isObservable(val) {

    return (val && typeof val.subscribe === 'function'
    && val.constructor && /Observable/.test(val.constructor.name));

};

除“null”和“undefined”原语外,所有其他原语都有构造函数属性。

除“null”和“undefined”原语外,所有其他原语都有构造函数属性。

未定义的和
null
没有
构造函数
属性

像数字这样的值似乎有一个
构造函数
,但确实有些“特殊”,因为


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

像数字这样的值似乎有一个
构造函数
,但确实有些“特殊”,因为


“包装”数字(
x=newnumber(42)
)是普通对象,您可以在其中存储其他属性。所以当
3
声明
Number
为其构造函数时,调用它不会生成与数字
3

相同类型的值。在您尝试执行的操作中使用
.constructor
属性是个坏主意,因为这消除了子类化的任何本质,也消除了调用方使用自己风格的可观察属性来支持所需契约的能力,但这不是你要找的名字。它还取消了在原始构造函数本身不是可观察对象的情况下使用混合对象或复合对象的功能。这些可能不是你想要禁止的事情

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

  • 测试
    instanceof
    ,查看它是否来自已知的基本对象
  • 测试对象,以查看其是否具有行为符合您要求的对象的已知和预期属性。这就是所谓的。如果它像鸭子一样呱呱叫,那么它一定是鸭子,即使你没有检查它的DNA,它也足以胜任你要做的事情
  • 我建议你扩展一下你所拥有的:

    return (val && 
            typeof val.subscribe === 'function' && 
            typeof val.unsubscribe === 'function')
    
    在合法的可观察对象上添加更多的属性/方法。你可以按照自己的意愿严格测试(如果你愿意,可以测试10个不同的方法,甚至调用几个没有副作用的方法,看看它们是否返回所需的值),但实际上,你可能只想确保它闻起来有点像是可观察的,然后如果调用方给你一个半成品的可观察值,这是他们的问题。你真正的目标是在开发人员犯编程错误时向他们提供建议,这样你就可以“尽早”在他们的开发过程中抛出一个异常,表明他们传递了错误类型的对象。最简单的嗅觉测试就足够了。您通常对测试次级分包不感兴趣


    没有理由测试比实际使用更多的属性。如果有人想制作自己版本的可观察对象,以支持您使用的属性,那么应该允许他们这样做,这样您就不必再担心了。如果他们试图使用看起来像可观察的东西,但是没有在对象上实现正确的接口,那么这就是他们没有给你一个合法的可观察的东西,在您的API上不是这样。

    使用
    .constructor
    属性来完成您要做的事情是个坏主意,因为这消除了子类化的本质,也消除了调用者使用自己风格的可观察性来支持所需契约的能力,但并不是您想要的名称。它还取消了在原始构造函数本身不是可观察对象的情况下使用混合对象或复合对象的功能。这些可能不是你想要禁止的事情

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

  • 测试
    instanceof
    ,查看它是否来自已知的基本对象
  • 测试对象,以查看其是否具有行为符合您要求的对象的已知和预期属性。这就是所谓的。如果它像鸭子一样呱呱叫,那么它一定是鸭子,即使你没有检查它的DNA,它也足以胜任你要做的事情
  • 我建议你扩展一下你所拥有的:

    return (val && 
            typeof val.subscribe === 'function' && 
            typeof val.unsubscribe === 'function')
    
    在合法的可观察对象上添加更多的属性/方法。你可以按照自己的意愿严格测试(如果你愿意,可以测试10个不同的方法,甚至调用几个没有副作用的方法,看看它们是否返回所需的值),但实际上,你可能只想确保它闻起来有点像是可观察的,然后如果调用方给你一个半成品的可观察值,这是他们的问题。你真正的目标是在开发人员犯了编程错误时向他们提供建议,这样你就可以“尽早”在他们的开发过程中抛出一个异常,表明他们犯了错误
    let a = {};    
    a.constructor = undefined;
    console.log (a.constructor); 
    // -> console shows: undefined