V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
• 请不要在回答技术问题时复制粘贴 AI 生成的内容
yantianqi
V2EX  ›  程序员

js 中对象的属性 hasOwnProperty

  •  
  •   yantianqi · 2017-08-30 21:30:52 +08:00 · 2608 次点击
    这是一个创建于 2671 天前的主题,其中的信息可能已经有所发展或是发生改变。

    在 underscore 中看到这样的代码,感觉有些奇怪

    // underscore 中的代码
    _.has = function (obj, key) {
        return obj != null && hasOwnProperty.call(obj, key);
        };
    

    这里用hasOwnProperty.call(obj, key) 有什么特殊意义吗?
    obj.hasOwnProperty(key)有区别吗?

    8 条回复    2017-08-31 10:21:57 +08:00
    xrr2016
        1
    xrr2016  
       2017-08-30 22:10:16 +08:00
    可能是为了不用去查找原型链吧
    kanezeng
        2
    kanezeng  
       2017-08-30 22:10:36 +08:00   ❤️ 3
    非要说不一样的话,就是避免 obj 如果重新定义了 hasOwnProperty 这个方法?
    比如 var obj = {
    hasOwnProperty(item) { return true; }
    }

    这时候如果你直接 obj.hasOwnProperty('随便什么') 返回都是 true。

    但是你用 Object.hasOwnProperty(obj, ’随便什么') 就会正确的返回 false。
    kanezeng
        3
    kanezeng  
       2017-08-30 22:11:04 +08:00
    非要说不一样的话,就是避免 obj 如果重新定义了 hasOwnProperty 这个方法?
    比如 var obj = {
    hasOwnProperty(item) { return true; }
    }

    这时候如果你直接 obj.hasOwnProperty('随便什么') 返回都是 true。

    但是你用 Object.hasOwnProperty.call(obj, ’随便什么') 就会正确的返回 false。
    cnnblike
        4
    cnnblike  
       2017-08-30 23:36:27 +08:00
    确保调用的是 Object 的原型里面的 hasOwnProperty,不一样的。

    仔细考虑一下调用的顺序,如果是 obj.hasOwnProperty(key),那么他会在这些上找:
    1.obj 本体
    2.obj 的原型链
    原型链上有任意一个对象有 hasOwnProperty,都会影响其行为。

    举个简单的例子,obj 原型为 obj_prototype,obj_prototype 原型为 object,而 obj_prototype 里面有个 hasOwnProperty,那么就出问题了。
    kfll
        5
    kfll  
       2017-08-30 23:42:59 +08:00 via Android
    不是所有对象都有 hasOwnProperty,比如 Object.create(null) 创建的对象
    doubleflower
        6
    doubleflower  
       2017-08-31 08:58:09 +08:00 via Android
    这时候可以看出来 python 设计比较先进,实例系统方法都是前后双下划线,不会和应用方法混淆
    meepo3927
        7
    meepo3927  
       2017-08-31 10:19:49 +08:00
    上面说的都对。

    underscore.js 毕竟是通用工具库,所以代码很严谨,需要考虑各种不常见的情况:
    1. obj 没有 hasOwnProperty 方法,直接 obj.hasOwnProperty 会报运行时错误;
    2. obj 上重新定义了 hasOwnProperty 方法,那么返回值是非预期的;
    3. obj 没有 hasOwnProperty 方法,但是其原型链上重新定义了 hasOwnProperty 方法,同上;

    嗯.
    meepo3927
        8
    meepo3927  
       2017-08-31 10:21:57 +08:00
    补充一下,还有一个好处如 1 楼所说,hasOwnProperty 是不查找原型链的,从性能上说,更好。

    当你有大量循环并且对象的原型链较深时,执行速度的差异会有所体现。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   3477 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 10:54 · PVG 18:54 · LAX 02:54 · JFK 05:54
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.