2
var F = function(){};
Object.prototype.a = function(){};
Function.prototype.b = function(){};

F既能访问到a,也能访问到b(Object 和 Function也同样, 但是所有的实例只能访问到a),F是Object 和 Function两个的实例, 那么 Object 和 Function 到底是什么关系?

这是我对 Object 和 Function 的了解

F instanceof Object
true
F instanceof Function
true
Object instanceof Function
true
Function instanceof Object
true



Object:
function Object() { [native code] }
Object.constructor function Function() { [native code] }
Function:
function Function() { [native code] }
Function.constructor == Function true


Object == Function false

能看出两个问题
1.Object 和 Function 互为实例
2.有相同的构造函数 function Function() { [native code] }
3.Object 和 Function 不相等

Number instanceof Number false
Number instanceof Function true
Number instanceof Object true
Number.constructor function Function() { [native code] }

Array instanceof Object true
Array instanceof Function true

4.其他基本类型或者非基本类型也都既是 Object的实例也是Function的实例

DevinnZ 241
2015-05-07 提问
6 个回答
19

已采纳

我来认真严肃的回答一下这个问题, 这其实是属于原型链的范畴。

以下限于个人理解, 有不对之处欢迎拍砖。
1. 首先ObjectFunction都是构造函数,而所有的构造函数的都是Function的实例对象. 因此ObjectFunction的实例对象
2. Function.prototypeObject的实例对象
3. 实例对象的原型(我们以__proto__来表示)会指向其构造函数的prototype属性, 因此 Object.__proto__ === Function.prototype, Function.__proto__ === Function.prototype, Function.prototype.__proto__ === Object.prototype
4. 当我们访问一个属性值的时候, 它会沿着原型链向上查找, 直到找到或者到Object.prototype.__proto__(为null)截止.

假如我们有以下例子:

javascriptvar foo = {},
    F = function(){};

Object.prototype.a = 'value a';
Function.prototype.b = 'value b';

console.log(foo.a)    // value a
console.log(foo.b)    // undefined
console.log(F.a)      // value a
console.log(F.b)      // value b

那么

  • foo.a的查找路径: foo自身: 没有 ---> foo.__proto__(Object.prototype): 找到value a
  • foo.b的查找路径: foo自身: 没有 ---> foo.__proto__(Object.prototype): 没有 ---> foo.__proto__.__proto__ (Object.prototype.__proto__): 没有
  • F.a的查找路径: F自身: 没有 ---> F.__proto__(Function.prototype): 没有 ---> F.__proto__.__proto__(Object.prototype): 找到value a
  • F.b的查找路径: F自身: 没有 ---> F.__proto__(Function.prototype): 找到value b

4.关于instanceof的结果不要仅从字面上理解, 它的计算规则是: 如果右侧构造函数的prototype属性能在左侧的对象的原型链中找到, 那么就返回true, 否则就返回false

  • Object intanceof Function: Object.__proto__ === Function.prototype, 因为结果为true
  • Function instanceof Object: Function.__proto__.__proto__ === Object.prototype, 因为结果也为true

至于你说的, ObjectFunction互为实例对象是不对的,ObjectFunction的实例对象, Function.prototypeObject的实例对象。

5.实例对象的constructor属性指向其构造函数, 因此Object.constructor === Function, Function.constructor === Function.

6.最后可以看一下这张图帮助理解:
jsobj

5

Object.prototype是所有对象的根源
Object.prototype只是挂载在Object函数对象上
Function.prototype构造自Object.prototype
Function.prototype 只是挂载在Function函数对象上
Object函数和Function函数构造自Function.prototype
Object字面量对象{}构造自Object.prototype
Object字面量对象{}.__proto__(原构造对象) === Object.prototype
Function函数 和 自定义函数 都继承(构造而成)自Function.prototype
Function.prototypeFunction.__proto__(原构造对象)相同
所以,是先有的Object.prototype,再有的Function.prototype,再有的FunctionObject函数对象

0
Object.__proto__
> function Empty() {}
Function.__proto__
> function Empty() {}

他们的隐式原型相同,所以相互 instanceof 都为 true.

0

有点乱,我讲下我的理解:
Object可以理解为object对象,也可以理解为Object方法,所以,他是Function的实例(Object方法)。
Function可以理解为方法对象,所以是Object对象的实例。

代码中的F先被赋值未一个Function的实例,这个时候继承了Function的方法和Function继承的Object的prototype上的方法。
对Object和Function添加方法后,Object被修改了,所以F上有了Object的新方法a。
修改Function没有影响F是因为,F已经被赋值了老的Function,已经是老Function的实例了,b方法给Function并不会影响到老Function的实例。

0

所有函数的原型本身就是继承Function.prototype,但是Function.prototype上面是无法进行修改的,所以你添加的方法是无法共享访问的,你可以说试试,这也是为什么所有函数都有call call就是存储在Function.prototype,但是她并不能修改

0

这个话题还是挺有意思的
@yizzuide @chenhao_ch 说的已经挺好了。还是想啰嗦几句由于js规定让人产生的困惑:
一、js中的所有东西全是对象(这个没有异议,而且是规定的)。所以任何东西的原型链都会指向Object.prototype,即xxx.__proto__[.__proto__(不定个数)]最终都会指向Object.prototype,然后Object.prototype.__proto__指向null(这里也没有异议,又是规定的),完成原形链的查找。

二、其实不管继承多少个自定义构造函数,我们对于原形链的理解都很清楚。比较难理解的地方就是Object和Funciton之间的关系。Object本身是一个可执行函数,所以Object._proto__ == Function.prototype很好理解。困惑的是Function.__proto__ == Function.prototype,可以看出Funciton是由自己构造来的。

三、理解如下例子

Function.__proto__.prototype  //undefined
Object.prototype.prototype    //undefined

四、说下楼主Funciton和Object实例访问不到b的原因
f = new F(); new关键字,内部是分这么几部完成的:
1、新建一个空对象 var obj = {};
2、给obj指定__proto__属性,改变this指向obj.__proto__ = F.prototype; F.call(obj,...arg);
3、返回obj对象或者F.call中return的对象。
所以,f是一个对象,而不是一个函数了。所以,f的原形链上不会走Funciton.prototype,因此也就找不到b属性了。

该答案已被忽略,原因:

撰写答案

推广链接