[译]JavaScript中,什么对象不是Object的实例?

原文:http://www.2ality.com/2012/08/instanceof-object.html


问题是: 什么对象不是Object的实例?换句话说就是:变量v是什么样的值,可以让下面的三个表达式都为true?

typeof v === "object"
v !== null
!(v instanceof Object)

1.关于v,我们知道些什么?

上面的表达式告诉我们关于v的两件事:它是一个对象,但他不是Object的实例.

1.1 v是一个对象

前两个表达式使用typeof操作符来确保v是一个对象.第二个表达式是必须的,因为typeof有个bug,那就是在操作原始值null时,返回"object".这样一来,v就是一个完完全全的对象了.

记得JavaScript中只有两种类型的值吗:原始值和对象值.原始值是只读的(不可变的),也就是说:你不能尝试在它身上创建或者修改属性值,这样的操作不会有任何效果:

> var str = "abc";

> str.foo = 123;
123
> str.foo
undefined

> str.length
3
> str.length = 1;
> str.length
3

原始值的比较是通过值来比较的,也就是说:一个值的内容决定了它是否和另外一个相同类型的值相等:

> "abc" === "abc"
true

不同的是,对象值是可变值,对象值之间是通过引用来比较的.每个对象值都有自己唯一的标识符.即便它们有相同的内容,两个对象也只有在拥有相同的标识符时才算相等:

> new String("abc") === new String("abc")
false
> {} === {}
false

> var obj = {};
> obj === obj
true
1.2 v不是Object的实例

第三个表达式告诉我们,v不是Object的实例.但这又意味着什么?在执行下面的表达式时

value instanceof type

instanceof操作符会检查type.prototype是否在value的原型链上.也就是说,如果我们自己实现一个instanceof函数,完全可以这么写(不考虑一些错误的检查,比如type为null等):

function myInstanceof(value, type) {
     return type.prototype.isPrototypeOf(value);
}

2.寻找一个没有原型的对象

因此,我们必须找到一个自身的原型链中没有Object.prototype的对象.没有一个内置的类型符合这个要求:

> Object.prototype.isPrototypeOf({})
true
> Object.prototype.isPrototypeOf([])
true
> Object.prototype.isPrototypeOf(/abc/)
true

不过,我们可以使用Object.create来创建一个没有任何原型的的对象,甚至也不继承Object.prototype:    

> var obj = Object.create(null)
undefined
> Object.getPrototypeOf(obj)
null
> Object.prototype.isPrototypeOf(obj)
false

obj没有任何标准的方法,比如toString()方法,但它仍然是一个对象,可以有属性和其他所有的对象特性.这样就发现了我们要找的v:

> obj instanceof Object
false
> typeof obj
'object'

另一个答案. 鉴于原型链必然有尽头,而这个尽头就是Object.prototype,该对象没有自己的原型,下面的代码证明了这一点:

> Object.prototype instanceof Object
false
> typeof Object.prototype
'object'

 其他内置类型的prototype属性都是有自己的原型的,比如Date:

> Object.getPrototypeOf(Date.prototype)
{}
译者注:我只答出了第二个答案.

3.参考

  1. JavaScript values: not everything is an object
  2. Improving the JavaScript typeof operator
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值