读书人

关于js的一切对象都承继自Object的质疑

发布时间: 2013-01-06 15:44:47 作者: rapoo

关于js的一切对象都继承自Object的质疑
通过这一句
console.info(Object.prototype instanceof Object);
结果输出false
故怀疑关于js的一切对象都继承自Object的质疑
欢迎大家积极讨论
[解决办法]
js的一切对象都继承自Object这个是js的设计理念,而Object.prototype不是Object的实例这个是设计上的技巧。在原型链中如果不断开这个的话,就变成死循环了。
[解决办法]
typeof Object.prototype == 'object'

总有个初始推动的把
[解决办法]
instanceof判断的是实例是否为某个类的实例,你这样用不对吧,prototype又不是实例。。
[解决办法]
楼主本身就用错了.

<script>
function theforever()
{
var t = 'I'm theforever @ csdn.net!';
this.ok = function() {
alert(t);
}
}
var a=new theforever();
alert(a instanceof theforever); //正确
alert(a.prototype instanceof theforever); //错误
</script>

[解决办法]
只能说prototype是一个特殊的属性,同时Object、Number、Function这些内置类型也是一种特殊对象(或者说类)。

大家看看这个:

Object instanceof Function; //true
Function instanceof Object; //true

这个够无语的,其实想想也不难理解。
prototype这个属性是特殊的,只有function才有(或者说类,或者说构造器),而prototype到底是不是Object?

Array.prototype instanceof Object; //true

我们发现Array的prototype确实是Object。这里要分析一下instanceof操作符,其实现原理是什么。如果是最新的chrome,大家可以试试Object.getPrototypeOf方法,可以反对对象的原型链。其实,在chrome的console下,不知道大家注意到对象的这个属性没有,那就是"__proto__"。instanceof操作符其实就是检查左侧的__proto__链上有没有右侧类的prototype存在。

Array.prototype.__proto__ === Object.prototype //chrome 下 true

所有的对象,包括内置的和运行时生成的,其原型链(在chrome下表现为__proto__)上的顶端都是Object.prototype,唯一只有一个对象没有__proto__属性,那就是Object.prototype。


Object.getPrototypeOf(Object.prototype); //null,或者说Object.prototype.__proto__ === null

但是,这并不能说明Object不是所有的对象的超类,prototype是一个特殊的属性,可以说Object.prototype就是Object是所有类的超类的证明和表现。

chrome的console下可以看得见__proto__,它是webkit实现prototype原型的一种手段,IE下是不可见的。
大家在chrome下试试这段代码,new这个操作符到底干了什么

function A(){}
function B(){}
a = new A();
a instanceof A; //true
a.__proto__ = B.prototype
a instanceof A; //false
a instanceof B; //true


[解决办法]
引用:
引用:instanceof判断的是实例是否为某个类的实例,你这样用不对吧,prototype又不是实例。。哦,可是这样function Teacher() {
}
console.info(Teacher.prototype instanceof Object);
返回true
按你的说法,Teacher.prototype也确实是O……


首先感谢LZ的问题 ..
其实这个问题也不难回答, 涉及到 JavaScript Core 的问题, 最直接的办法就是去查 ECMA-262 (What??还不知道ECMA-262是神马??)

// LZ一直在说的都是继承啊, 原型啊神马的, 而又是用 instanceof 这个运算符去验证的
// 那我们不妨去看一看在JS标准中 instanceof 这个运算符到底是如何工作的:

var isInstanceOf = A instanceof B;
/*
算法是:
Step 1) 如果 A 不是对象, 直接返回 false
Step 2) 令 O = B.prototype
Step 3) 如果 O 不是对象类型, 抛出 TypeError 异常
Step 4) 循环 {
A = A.[[Prototype]];


if (A == null) return false;
if (A == O) return true;
}
*/
//==============
//下面来分析LZ给出的两段代码
// No.1
Object.prototype instanceof Object // false
/*
根据上面给出的算法, 可得:
O = Object.prototype;
V = Object.prototype.[[Prototype]]; (第一次循环)
由常识(算是常识吗, 原型链结束于null)可得 Object.protytype.[[Prototype]] == null
所以, 根据 Step 4 里的第一个 if() 直接返回 false.
也就是LZ看到的最终结果 false
*/

// No.2
function Teacher() {}
Teacher.prototype instanceof Object; // true
/*
根据上面给出的算法, 可得:
O = Object.prototype;
A = Teacher.prototype.[[Prototype]] = Object.prototype; (第一次循环)
根据算法 O == A, 返回 true
*/



接下来 稍做解释

Teacher.prototype.[[Prototype]] = Object.prototype;
/*
Teacher.prototype 为 new Object() 加一点操作得到(),
所以 Teacher.prototype.[[Prototype]] = Object.prototype
*/


另外也建议LZ了解一下 [[Prototype]] 和 prototype 的区别

读书人网 >JavaScript

热点推荐