代码之家  ›  专栏  ›  技术社区  ›  Jonathan Lonowski

为什么instanceof对于某些文本返回false?

  •  248
  • Jonathan Lonowski  · 技术社区  · 18 年前
    "foo" instanceof String //=> false
    "foo" instanceof Object //=> false
    
    true instanceof Boolean //=> false
    true instanceof Object //=> false
    false instanceof Boolean //=> false
    false instanceof Object //=> false
    
    12.21 instanceof Number //=> false
    /foo/ instanceof RegExp //=> true
    
    // the tests against Object really don't make sense
    

    数组文字和对象文字匹配。。。

    [0,1] instanceof Array //=> true
    {0:1} instanceof Object //=> true
    

    为什么不是所有人?或者,他们为什么不都去呢 不
    那么,它们是什么样的例子呢?

    9 回复  |  直到 6 年前
        1
  •  470
  •   leggetter    9 年前

    Mozilla API docs :

    var color1 = new String("green");
    color1 instanceof String; // returns true
    var color2 = "coral";
    color2 instanceof String; // returns false (color2 is not a String object)
    

    我找不到用代码构造基元类型的任何方法,也许这是不可能的。这可能就是为什么人们使用 typeof "foo" === "string" instanceof .

    记住这类事情的一个简单方法是问自己“我想知道什么是理智的、容易学的”?不管答案是什么,Javascript做的是另一件事。

        2
  •  115
  •   Mark Amery Harley Holcombe    11 年前

    我使用:

    function isString(s) {
        return typeof(s) === 'string' || s instanceof String;
    }
    

    因为在JavaScript中,字符串可以是文本或对象。

        3
  •  69
  •   nicodemus13    9 年前
    控制台日志(typeof true);//布尔值 console.log(typeof 0);//数字 console.log(typeof“”);//一串 console.log(typeof未定义);//未定义 console.log(typeof[]);//对象 console.log(typeof{});//对象 console.log(typeof函数(){});//作用

    如您所见,对象、数组和值 null 都被视为对象( null 是对不存在的对象的引用)。函数之所以与众不同,是因为它们是一种特殊类型的可调用对象。然而,它们仍然是对象

    console.log(新布尔值的类型(true));//对象
    console.log(新编号的类型(0));//对象
    

    正如您所看到的,当基本值分别包装在 布尔 、 数字 和 字符串 构造函数中时,它们将成为对象。 instanceof 运算符仅适用于对象(这就是它返回 false 基本值的原因):

    console.log(布尔值的真实例);//错误的
    console.log(0 instanceof Number);//错误的
    console.log(布尔值的新布尔值(真)实例);//符合事实的
    console.log(新字符串(“”)instanceof String);//符合事实的
    

    幸运的是,这个问题有一个简单的解决方案。 toString 的默认实现(即在 Object.prototype.toString 上本机定义的)返回基本值和对象的内部 [[Class]] 属性:

    函数类(值){
    返回Object.prototype.toString.call(值);
    }
    
    console.log(classOf(true));//[对象布尔值]
    console.log(classOf(0));//[物件编号]
    console.log(classOf(“”);//[对象字符串]
    log(classOf(新布尔值(true));//[对象布尔值]
    console.log(classOf(新编号(0));//[物件编号]
    

    值的内部 [[Class]] 属性比值的 类型有用得多。我们可以使用 Object.prototype.toString 创建自己(更有用)的 typeof 操作符,如下所示:

    函数类型(值){
    返回Object.prototype.toString.call(value.slice)(8,-1);
    }
    
    console.log(typeOf(true));//布尔值
    console.log(typeOf(0));//数字
    console.log(typeOf(new Boolean(true));//布尔值
    console.log(typeOf(新编号(0));//数字
    console.log(typeOf(新字符串(“”));//一串
    
    

    希望这篇文章有帮助。要了解原语和包装对象之间的差异,请阅读以下博文:JavaScriptPrimitives的秘密生活

    console.log(typeof true);           // boolean
    console.log(typeof 0);              // number
    console.log(typeof "");             // string
    console.log(typeof undefined);      // undefined
    console.log(typeof null);           // object
    console.log(typeof []);             // object
    console.log(typeof {});             // object
    console.log(typeof function () {}); // function
    

    正如您所看到的,对象、数组和值null都被认为是物体吗(是对不存在的对象的引用)。函数之所以与众不同,是因为它们是一种特殊类型的函数可调用物体。然而,它们仍然是对象。

    true,0""和它们不是对象。它们是JavaScript中的基本值。但是布尔、数字和字符串也有构造函数Boolean,Number和String分别包装各自的原语以提供附加功能:

    console.log(typeof new Boolean(true)); // object
    console.log(typeof new Number(0));     // object
    console.log(typeof new String(""));    // object
    

    如您所见,当原语值包装在布尔值数字和构造函数,它们分别成为对象。这个instanceof运算符仅适用于对象(这就是它返回的原因)false

    console.log(true instanceof Boolean);              // false
    console.log(0 instanceof Number);                  // false
    console.log("" instanceof String);                 // false
    console.log(new Boolean(true) instanceof Boolean); // true
    console.log(new Number(0) instanceof Number);      // true
    console.log(new String("") instanceof String);     // true
    

    正如你们所看到的typeof和运算符不足以测试值是布尔值、数字还是字符串-仅适用于原始布尔、数字和字符串;和运算符不适用于基本布尔、数字和字符串。

    幸运的是,这个问题有一个简单的解决方案。的默认实现toStringObject.prototype.toString)返回内部[[Class]]基本体值和对象的属性:

    function classOf(value) {
        return Object.prototype.toString.call(value);
    }
    
    console.log(classOf(true));              // [object Boolean]
    console.log(classOf(0));                 // [object Number]
    console.log(classOf(""));                // [object String]
    console.log(classOf(new Boolean(true))); // [object Boolean]
    console.log(classOf(new Number(0)));     // [object Number]
    console.log(classOf(new String("")));    // [object String]
    

    内部值的属性比类型价值。我们可以使用Object.prototype.toString创建我们自己的(更有用的)版本类型

    function typeOf(value) {
        return Object.prototype.toString.call(value).slice(8, -1);
    }
    
    console.log(typeOf(true));              // Boolean
    console.log(typeOf(0));                 // Number
    console.log(typeOf(""));                // String
    console.log(typeOf(new Boolean(true))); // Boolean
    console.log(typeOf(new Number(0)));     // Number
    console.log(typeOf(new String("")));    // String
    

    希望这篇文章有帮助。要了解原语和包装对象之间的差异,请阅读以下博文:JavaScriptPrimitives的秘密生活

        4
  •  38
  •   user144049    17 年前

    您可以使用构造函数属性:

    'foo'.constructor == String // returns true
    true.constructor == Boolean // returns true
    
        5
  •  12
  •   BoffinBrain    9 年前
     typeof(text) === 'string' || text instanceof String; 
    

    1. var text="foo"; //这一类型的工作可以

    2. String text= new String("foo"); //instanceof将起作用

        6
  •  3
  •   HKTonyLee    7 年前

    这在ECMAScript规范中定义 Section 7.3.19 Step 3 : If Type(O) is not Object, return false.

    换句话说,如果 Obj 在里面 Obj instanceof Callable 不是一个对象,而是 instanceof 会对电源短路吗 false 直接地

        7
  •  1
  •   Robby Harris    9 年前

    我相信我已经找到了一个可行的解决方案:

    Object.getPrototypeOf('test') === String.prototype    //true
    Object.getPrototypeOf(1) === String.prototype         //false
    
        8
  •  0
  •   Belhadjer Samir    5 年前

    基本包装类型是引用类型,每当字符串、数字或布尔值出现时,会在后台自动创建这些类型 已阅读。例如:

    var name = "foo";
    var firstChar = name.charAt(0);
    console.log(firstChar);
    

    这就是幕后发生的事情:

    // what the JavaScript engine does
    var name = "foo";
    var temp = new String(name);
    var firstChar = temp.charAt(0);
    temp = null;
    console.log(firstChar);
    

    因为第二行像对象一样使用字符串(原语), JavaScript引擎创建一个String实例,以便charAt(0)将 检查 this

    这个 运算符 运算符返回false,因为临时对象是 仅在读取值时创建。因为instanceof实际上不读取 任何东西,都不会创建临时对象,它告诉我们值不是

        9
  •  -2
  •   mko    11 年前

    对我来说

    "str".__proto__ // #1
    => String
    

    所以 "str" istanceof String 应该回来 true 因为istanceof的工作原理如下:

    "str".__proto__ == String.prototype // #2
    => true
    

    和 #2

    #1是错误的

    __proto__ 是非标准属性,因此请使用标准属性: Object.getPrototypeOf

    Object.getPrototypeOf("str") // #3
    => TypeError: Object.getPrototypeOf called on non-object
    

    现在两种表达方式之间没有混淆 #2 和 #3

        10
  •  -8
  •   sth    16 年前

    或者,您可以像这样创建自己的函数:

    function isInstanceOf(obj, clazz){
      return (obj instanceof eval("("+clazz+")")) || (typeof obj == clazz.toLowerCase());
    };
    

    用法:

    isInstanceOf('','String');
    isInstanceOf(new String(), 'String');
    

    这两者都应该是真的。

    推荐文章