V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐关注
Meteor
JSLint - a JavaScript code quality tool
jsFiddle
D3.js
WebStorm
推荐书目
JavaScript 权威指南第 5 版
Closure: The Definitive Guide
pabupa
V2EX  ›  JavaScript

啊?这……

  •  
  •   pabupa · 2020-07-23 18:59:51 +08:00 · 9430 次点击
    这是一个创建于 1582 天前的主题,其中的信息可能已经有所发展或是发生改变。
    "    " instanceof String; // False !!!!!!!!!!!!!!
    

    你内部怎么实现的,跟我有社么关系呀?你不能让他保持一致吗?!

    第 1 条附言  ·  2020-07-23 21:09:23 +08:00
    #python
    isinstance("  ", str)  # True
    
    
    # ruby
    puts "   ".instance_of?(String) ; # True
    
    69 条回复    2020-08-03 18:22:47 +08:00
    GM
        1
    GM  
       2020-07-23 19:07:05 +08:00
    不能。

    爱用不用,不用就滚~~~~~
    Touchevent
        2
    Touchevent  
       2020-07-23 19:09:10 +08:00
    暴躁老哥。。
    wellsc
        3
    wellsc  
       2020-07-23 19:11:22 +08:00 via iPhone
    Js 三元一体.jpg
    DoodleSit
        4
    DoodleSit  
       2020-07-23 19:12:28 +08:00
    typeof 不香吗~~
    instanceof 代表是实例的意思,前提是要实例化( new )
    yongjing
        5
    yongjing  
       2020-07-23 19:13:33 +08:00
    RTFM instanceof 只校验对象
    pabupa
        6
    pabupa  
    OP
       2020-07-23 21:10:14 +08:00
    @GM ?????????
    pabupa
        7
    pabupa  
    OP
       2020-07-23 21:13:08 +08:00
    @yongjing
    @DoodleSit

    https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators/Object_initializer

    "可以通过 new Object(),Object.create()方法,或者******使用字面量标记(初始化标记)初始化对象******。"
    ViggoSite
        8
    ViggoSite  
       2020-07-23 21:14:48 +08:00
    typeof 不香吗~~
    pabupa
        9
    pabupa  
    OP
       2020-07-23 21:21:47 +08:00 via Android
    @ViggoSite typeof 返回的是字符串,还需要再比较一次。
    MintZX
        10
    MintZX  
       2020-07-23 21:29:52 +08:00 via iPhone
    我没理解,这有什么问题?

    前者是模版字符,后者是对象。当然不是一个东西。

    python 和 ruby 是一个类那就是 True,js 不是一个类那就不是 true 。你想比较的话用 new String()好了。
    morethansean
        11
    morethansean  
       2020-07-23 21:30:05 +08:00
    @ViggoSite 你引用的这篇文章里不是写了嘛, ```An object initializer is a comma-delimited list of zero or more pairs of property names and associated values of an object, enclosed in curly braces ({}).``` string literal 并不是 object, instanceof 会返回 false.
    ViggoSite
        12
    ViggoSite  
       2020-07-23 21:31:03 +08:00
    @pabupa 那....有啥问题吗?

    typeof " " == "string"
    ViggoSite
        13
    ViggoSite  
       2020-07-23 21:32:38 +08:00
    @morethansean @错了(⊙_⊙;)…
    jinliming2
        14
    jinliming2  
       2020-07-23 21:36:34 +08:00   ❤️ 2
    String 是类,你可以 new String
    "" 是 string,基本数据类型之一,不是 object
    既然连 object 都不是,怎么可能 instanceof ?
    "" !== new String(""),因为数据类型不一样,一个是 string,一个是 object 。

    顺便,@pabupa #7,你能把那一段复制完吗?
    可以通过 new Object(),Object.create()方法,或者使用字面量标记**(初始化标记)**初始化对象。 **一个对象初始化器,由花括号 /大括号 ({}) 包含的一个由零个或多个对象属性名和其关联值组成的一个逗号分隔的列表构成**。
    所以,只有 {} 出来的才是对象!
    hirasawayui
        15
    hirasawayui  
       2020-07-23 21:56:37 +08:00
    new String(" are you ok? ") instanceof String // true
    HiCode
        16
    HiCode  
       2020-07-23 22:26:42 +08:00
    [] == []

    false
    pigmen
        17
    pigmen  
       2020-07-23 22:30:30 +08:00
    这个真不怪 js,是你用错了
    watanuki
        18
    watanuki  
       2020-07-23 22:30:44 +08:00
    搜索 wtfjs 有惊喜
    yujiff
        19
    yujiff  
       2020-07-23 22:41:25 +08:00
    我爱 V2,高人多且直接、热心!
    zhengjian
        20
    zhengjian  
       2020-07-23 23:07:12 +08:00
    new String(" ") instanceof String;
    yanguango
        21
    yanguango  
       2020-07-24 02:02:06 +08:00   ❤️ 1
    Mutoo
        22
    Mutoo  
       2020-07-24 07:36:11 +08:00
    可以自己写一个 instanceOf 来判断: 原理是追踪对象的 __proto__ 链,能否找到目标的原型。

    " ".__proto__ === String.prototype // true;
    Mutoo
        23
    Mutoo  
       2020-07-24 07:56:45 +08:00
    lizz666
        24
    lizz666  
       2020-07-24 08:35:53 +08:00
    你左边的是普通字面量,又不是字面量对象,你要分清楚,字面量对象是指直接 `{}` 这种形式的,`" "` 这种只是普通字面量
    你可以看看这个: https://github.com/lizhongzhen11/lizz-blog/issues/75#instanceof (结合规范和 MDN 理解下)
    lizz666
        25
    lizz666  
       2020-07-24 08:38:14 +08:00
    另外关于 instanceof 设计历史,你可以看 https://github.com/doodlewind/js-20-years-cn/blob/master/part-2.md#%E5%AE%9A%E4%B9%89-ecmascript-3 中相关内容
    murmur
        26
    murmur  
       2020-07-24 08:42:55 +08:00
    instanceof 我记得还有跨 iframe 的坑 ,所以判断 array 才会有那么复杂的写法
    free9fw
        27
    free9fw  
       2020-07-24 08:48:33 +08:00
    String.prototype.constructor(" ") instanceof String 与 new String(" ") instanceof String
    true 的区别
    xingyuc
        28
    xingyuc  
       2020-07-24 09:38:10 +08:00
    标题党先打死 hhh
    xiaoyu8740
        29
    xiaoyu8740  
       2020-07-24 09:44:52 +08:00
    拜托 先好好学学基础
    joesonw
        30
    joesonw  
       2020-07-24 09:49:06 +08:00
    @HiCode 数组和对象是指针比较, 肯定不一样啊. 你换哪个语言都不行啊.
    ChanKc
        31
    ChanKc  
       2020-07-24 10:06:34 +08:00 via Android   ❤️ 14
    JS 就是设计上有问题,为什么楼上那么多人不愿意承认?
    Vegetable
        32
    Vegetable  
       2020-07-24 10:18:49 +08:00
    这是不是弱类型造成的认知困难?
    faceRollingKB
        33
    faceRollingKB  
       2020-07-24 10:18:51 +08:00
    确实有这种问题,你需要使用 object wrapper 做一下装箱:Object(' ') instanceof String // true

    https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/Object
    VDimos
        34
    VDimos  
       2020-07-24 10:19:53 +08:00 via Android
    一般都多种方法判断的,我一般用 Object.prototype.toString 来判断
    ares586
        35
    ares586  
       2020-07-24 10:20:43 +08:00
    每个语言都有不足。。JS 能兼容,不像 py2 -> py3 已经不错了
    vivipure
        36
    vivipure  
       2020-07-24 10:59:16 +08:00
    new String(' ') instanceof String. // true
    ' ' instanceof String // false
    ' '.__proto__.contrucotr // undefined
    new String(' ').__proto__.constructor // String()

    ------------

    你直接声明的字符串是基本类型,不是通过实例生成的对象 所以 instanceof 没用

    建议 Object.prototype.toString.call() 万能的
    imnaive
        37
    imnaive  
       2020-07-24 11:49:38 +08:00
    瑕不掩瑜,你就当是断臂维纳斯了。
    HiCode
        38
    HiCode  
       2020-07-24 12:07:35 +08:00
    @joesonw 你没眼花吧?

    第一个是[]

    第二个也是[]

    自己复制了去浏览器执行看看。
    HiCode
        39
    HiCode  
       2020-07-24 12:10:44 +08:00
    @joesonw

    php:

    var_dump([] == []);

    true

    python:

    [] == []

    true

    你都去试试!
    MyouiSouth
        40
    MyouiSouth  
       2020-07-24 12:48:55 +08:00
    js 设计上有问题和楼主使用错误不冲突啊,大家承认了 js 的设计问题楼主的" " instanceof String 也不会变成 true 呀,为啥纠正使用错误变成了不承认 js 的设计问题呢,我就算承认了我也没办法纠正 js 的设计问题啊,委屈哭了呜呜呜
    ChanKc
        41
    ChanKc  
       2020-07-24 13:01:29 +08:00 via Android   ❤️ 1
    @MyouiSouth 在这个问题上,JS 和楼主之间,我觉得 JS 是更应该被 blamed 的
    Rwing
        42
    Rwing  
       2020-07-24 13:04:19 +08:00
    当初 10 天设计出来的语言,你能指望他有多完备?这不慢慢在补么
    AmiKara
        43
    AmiKara  
       2020-07-24 13:24:11 +08:00
    @joesonw js 的某些地方确实有问题,但是这个问题完全是楼主自己使用错误,js 里的基本数据类型和引用类型概念不一样,instanceof 查询的是元素原型链中的引用类型
    LokiSharp
        44
    LokiSharp  
       2020-07-24 13:45:55 +08:00
    JS 太多地方是反常识和反直觉的
    assad
        45
    assad  
       2020-07-24 13:47:50 +08:00
    宇宙变态语言,没啥的,总会让你惊不惊喜意不意外!
    DOLLOR
        46
    DOLLOR  
       2020-07-24 13:51:17 +08:00   ❤️ 2
    啊ニマビ,这니마비。
    能不能起一个正常一点的标题?
    能不能起一个正常一点的标题?
    能不能起一个正常一点的标题?
    joesonw
        47
    joesonw  
       2020-07-24 13:52:40 +08:00
    @HiCode []不是数组是什么, 字符串?
    byzf
        48
    byzf  
       2020-07-24 13:58:56 +08:00
    这都不算三位一体, string literal 不是 new string('').

    你这顶多是吃屎心蛋糕, 来发帖问为什么蛋糕上没有奶油.
    zh1997
        49
    zh1997  
       2020-07-24 14:02:36 +08:00
    #php
    explode(分隔符, 源字符)

    str_replace(被替换字符, 替换字符, 源字符)

    strpos(源字符, 查找字符)

    一直搞混,为什么不能把源字符统一放左边
    chenalex
        50
    chenalex  
       2020-07-24 14:17:47 +08:00
    @vivipure
    ' '.__proto__.contrucotr // undefined
    contrucotr => constructor
    所以 ' '.__proto__.constructor // String
    lovecy
        51
    lovecy  
       2020-07-24 14:19:38 +08:00
    啊这。。。懂得都懂!
    不会真有人不知道吧?不会吧不会吧不会吧?
    非杠非黑,无意冒犯,你在教 JavaScript 做事?
    rick2c
        52
    rick2c  
       2020-07-24 14:22:46 +08:00
    就这?
    fyxtc
        53
    fyxtc  
       2020-07-24 15:07:58 +08:00   ❤️ 1
    标题不能加上相关描述吗 ”js 空串 string 实例判断问题",很难?
    camillo
        54
    camillo  
       2020-07-24 16:29:20 +08:00
    主题标题
    请在标题中描述内容要点。如果一件事情在标题的长度内就已经可以说清楚,那就没有必要写正文了。
    TargaryenChen
        55
    TargaryenChen  
       2020-07-24 17:46:25 +08:00
    @murmur 我也遇到过,因为每个 iframe 有他们自己的内部 Class,你在一个 window.top 中 var a = new Array(), 在 iframe 中 a instanceof Array === false
    CEBBCAT
        56
    CEBBCAT  
       2020-07-24 18:06:03 +08:00
    @lovecy #50 @rick2c #51 不怕被站长 Deactivate 么……
    dbow
        57
    dbow  
       2020-07-24 18:21:31 +08:00
    不要有误会,  String 是个函数,不是个其它语言意义上的 type,  instanceof 是判断 prototype 用的,不是判断类型的。 
    javascript 里没有常规的 type, 只有 object 。  let a = new String(""); a instanceof String 这样是成立的,表示 a 的 prototype 是 String 。
    azh7138m
        58
    azh7138m  
       2020-07-24 18:37:41 +08:00
    @ChanKc
    > JS 就是设计上有问题,为什么楼上那么多人不愿意承认?

    JS 设计上的问题确实很多,但这与楼主不够了解 JS 并不冲突,是两回事
    mdn 里面也举了这个例子,我觉得并没有什么问题
    虽然不求每个人都能读一下标准,但是看看 mdn 总没啥门槛吧
    Cbdy
        59
    Cbdy  
       2020-07-24 18:41:52 +08:00 via Android
    js 就是设计得比较糙,要设计严谨去看 java
    ChanKc
        60
    ChanKc  
       2020-07-24 18:47:16 +08:00
    @azh7138m 我觉得楼主是知道了这个输出结果,然后吐槽这个设计
    要不也未免太低估楼主的学习能力了
    ChanKc
        61
    ChanKc  
       2020-07-24 19:00:38 +08:00
    @jinliming2 #14 啊,我知道基本数据类型什么的。但我觉得 String 还区分基本数据类型和,呃……你说的类。可是既然现实中根本没人真的会用 new String,为什么不就合成一个呢?
    你看 BigInt 。BigInt(1)会产生一个新的 BigInt,Object.getPrototypeOf(BigInt(1))可以拿到它的原型。而 new BigInt 则会抛出异常,所以几乎永远都不会产生 x instanceof BigInt 为 true 的可能,除非你干下面这种事情
    Object.create(Object.getPrototypeOf(BigInt(1))) instanceof BigInt
    在做 BigInt 的时候我觉得 TC39 的人一定注意到了这个问题所以做得比 String 要好了一些。但是过去的事情,像楼主这样吐槽一下也是挺有乐趣的事情。
    Java 的那帮人似乎确实有想过合二为一,Valhalla 好像就在做类似的事情
    https://cr.openjdk.java.net/~briangoetz/valhalla/sov/02-object-model.html
    ChanKc
        62
    ChanKc  
       2020-07-24 19:02:17 +08:00
    @ChanKc 脑子短路,第二句是“但我觉得为什么 String 还要区分基本数据类型和,呃……你说的类呢?“
    ChanKc
        63
    ChanKc  
       2020-07-24 19:02:38 +08:00
    @ChanKc “但我想……”
    DOLLOR
        64
    DOLLOR  
       2020-07-24 20:16:20 +08:00
    @ChanKc
    当年被迫模仿 java 创造了 js,连糟粕也一起模仿来咯。明明有基本类型,还非要为面向对象而面向对象,搞什么乱七八糟的“包装类”。每次都得反反复复解释新人为什么 new 两个相同的 String 用==相比却得到 false 。现在看到 java 来写前端的,还偶尔看见在 js 里 new String 的,简直可笑。
    robinlovemaggie
        65
    robinlovemaggie  
       2020-07-24 22:02:44 +08:00
    推荐看一下 Dan Abramov 的 justjavascript 课程,你需要一个重塑一下 mental model 来理解 JS
    szzhiyang
        66
    szzhiyang  
       2020-07-24 22:03:32 +08:00
    @imnaive 不是瑕不掩瑜,是瑜不掩瑕。
    wi
        67
    wi  
       2020-07-25 10:07:16 +08:00
    不会写标题就不要发帖
    lovecy
        68
    lovecy  
       2020-07-27 10:36:53 +08:00
    @lovecy [doge][doge][doge]
    @CEBBCAT 只是在玩梗,忘加狗头了[doge][doge][doge]
    rproud
        69
    rproud  
       2020-08-03 18:22:47 +08:00
    Object instanceof Function
    // true
    Function instanceof Object
    // true
    ![] == []
    // true
    !new Boolean(false)
    // false
    😈
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   985 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 21:16 · PVG 05:16 · LAX 13:16 · JFK 16:16
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.