js 中对象的属性 hasOwnProperty

2017-08-30 21:30:52 +08:00
 yantianqi

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

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

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

2599 次点击
所在节点    程序员
8 条回复
xrr2016
2017-08-30 22:10:16 +08:00
可能是为了不用去查找原型链吧
kanezeng
2017-08-30 22:10:36 +08:00
非要说不一样的话,就是避免 obj 如果重新定义了 hasOwnProperty 这个方法?
比如 var obj = {
hasOwnProperty(item) { return true; }
}

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

但是你用 Object.hasOwnProperty(obj, ’随便什么') 就会正确的返回 false。
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
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
2017-08-30 23:42:59 +08:00
不是所有对象都有 hasOwnProperty,比如 Object.create(null) 创建的对象
doubleflower
2017-08-31 08:58:09 +08:00
这时候可以看出来 python 设计比较先进,实例系统方法都是前后双下划线,不会和应用方法混淆
meepo3927
2017-08-31 10:19:49 +08:00
上面说的都对。

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

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

当你有大量循环并且对象的原型链较深时,执行速度的差异会有所体现。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/387000

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX