將欲廢之,必固興之;將欲奪之,必固與之。——《道德經》javascript
基本上都知道原型链的尽头指向null
,那么Function.prototype
、Object.prototype
、null
、Function.prototype.__proto__
、Object.prototype.__proto__
、function、object
之间的关系是什么,下面慢慢来记录一下。c#
Object 构造函数建立一个对象包装器。JavaScript中的全部对象都来自 Object
;全部对象从Object.prototype
继承方法和属性,尽管它们可能被覆盖。浏览器
Object 做为构造函数时,其 [[Prototype]] 内部属性值指向 Function.prototype函数
Object.__proto__ === Function.prototype; // true
复制代码
Object.prototype
表示 Object
的原型对象,其 [[Prototype]]
属性是 null
,访问器属性 __proto__
暴露了一个对象的内部 [[Prototype]]
。Object.prototype
是浏览器底层根据 ECMAScript 规范创造的一个对象。post
经过字面量实例化一个object
,它的__proto__
指向Object.prototype
。ui
var obj = {};
obj.__proto__ === Object.prototype; // true
复制代码
而经过new Object实例化一个object
,它的__proto__
指向Object.prototype
。spa
var obj = new Object;
obj.__proto__ === Object.prototype; // true
复制代码
对象类型的成员,标准内置构造器 Function的一个实例,而且可作为子程序被调用。 注: 函数除了拥有命名的属性,还包含可执行代码、状态,用来肯定被调用时的行为。函数的代码不限于 ECMAScript。
Function构造函数建立一个新的Function
对象。在JavaScript中每一个函数实际上都是一个Function
对象。
全局的Function
对象没有本身的属性和方法, 可是由于它自己也是函数,因此它也会经过原型链从Function.prototype
上继承部分属性和方法。Function.prototype
也是一个“函数对象“,其[[prototype]]
内部属性值指向Object.prototype
。
Function.prototype 的 [[Class]] 属性是 Function,因此这是一个函数,但又不大同样。
Function.prototype; // ƒ () { [native code] }
Function.prototype.prototype; // undefined
复制代码
用 Function.prototype.bind 建立的函数对象没有 prototype 属性。
let foo = Function.prototype.bind();
foo.prototype; // undefined
复制代码
Function.prototype
是引擎建立出来的函数,引擎认为不须要给这个函数对象添加 prototype
属性,否则 Function.prototype.prototype…
将无休无止而且没有存在的意义。
Function.prototype.__proto__
指向Object.prototype
。
Function.prototype.__proto__ === Object.prototype; // true
复制代码
Function
构造函数是一个函数对象,其 [[Class]]
属性是 Function
。Function
的 [[Prototype]]
属性指向了 Function.prototype
,即
Function.__proto__ === Function.prototype; // true
复制代码
实例化一个Function
,它的__proto__
指向Function.prototype
。
function foo () {}
foo.__proto__ === Function.prototype; // true
// foo.__proto__ => Function.prototype => Function.prototype.__proto__ => Object.prototype => Object.prototype.__proto__ => null
复制代码
通过上面对Object
和Function
的阐述,延伸出来几个问题以下:
在忽滤null
在原型链上时,原型链的尽头(root)是Object.prototype
。全部对象均从Object.prototype
继承属性。
Function.prototype
和Function.__proto__
为同一对象。
Object/Array/String
等等构造函数本质上和Function
同样,均继承于Function.prototype
。 Function.prototype
直接继承root(Object.prototype
)。
// Function.prototype继承了Object.prototype
Function.prototype.__proto__ === Object.prototype; // true
Function.prototype instanceof Object; // true
Function.prototype instanceof Function; // false
// Object Array Function 等等构造函数继承了Function.prototype
Function instanceof Function; // true
Array instanceof Function; // true
Object instanceof Function; // true
Function instanceof Object; // true
复制代码
经过上面代码知道继承的原型链大体是: Object.prototype(root)<---Function.prototype<---Function|Object|Array...。
上面的会出现一个比较奇特的现象以下:
Function.__proto__ === Function.prototype;
复制代码
Function
对象是否是由Function
构造函数建立的实例?
Function instanceof Object; // true
Object instanceof Function; // true
Object instanceof Object; // true
Function instanceof Function; // true
复制代码
为何Function instanceof Object
为true
,Object instanceof Function
也为true
,那么他们究竟是什么关系?
先要了解清楚Function.prototype
和Object构造函数
以下: 回归规范,摘录2点:
Function.prototype
是个不一样于通常函数(对象)的函数(对象)。The Function prototype object is itself a Function object (its [[Class]] is "Function") that, when invoked, accepts any arguments and returns undefined. The value of the [[Prototype]] internal property of the Function prototype object is the standard built-in Object prototype object (15.2.4). The initial value of the [[Extensible]] internal property of the Function prototype object is true. The Function prototype object does not have a valueOf property of its own; however, it inherits the valueOf property from the Object prototype Object.
上面的能够总结为:
Function.prototype
像普通函数同样能够调用,但老是返回undefined
。
普通函数其实是Function
的实例,即普通函数继承于Function.prototype
。func.__proto__ === Function.prototype
。
Function.prototype
继承于Object.prototype
,而且没有prototype
这个属性。func.prototype
是普通对象,Function.prototype.prototype
是null
。
因此,Function.prototype
实际上是个另类的函数,能够独立于/先于Function产生。
Object
自己是个(构造)函数,是Function
的实例,即Object.__proto__
就是Function.prototype
。
The value of the [[Prototype]] internal property of the Object constructor is the standard built-in Function prototype object. The value of the [[Prototype]] internal property of the Object prototype object is null, the value of the [[Class]] internal property is "Object", and the initial value of the [[Extensible]] internal property is true.
Function
对象是由Function
构造函数建立的一个实例?
Yes 的部分: 按照 JavaScript
中“实例”的定义,a
是 b
的实例即 a instanceof b
为 true
,默认判断条件就是 b.prototype
在 a
的原型链上。而 Function instanceof Function
为 true,本质上即 Object.getPrototypeOf(Function) === Function.prototype
,正符合此定义。
No 的部分: Function
是 built-in
的对象,也就是并不存在“Function
对象由Function
构造函数建立”这样显然会形成鸡生蛋蛋生鸡的问题。实际上,当你直接写一个函数时(如 function f() {}
或 x => x
),也不存在调用 Function
构造器,只有在显式调用 Function
构造器时(如 new Function('x', 'return x')
)才有。
我的偏向先有的Function.prototype
,再有的function Function
,全部构造函数本质上都是集成于Function.prototype
,因此Function.__proto__ === Function.prototype
。
// Function.__proto__、Function.prototype指向同一个对象,Function.prototype.__proto__指向Object.prototype
// Function.__proto__ => Function.prototype.__proto__ => Object.prototype => Object.prototype.__proto__ => null
Function instanceof Object; // true
// Object做为构造函数继承自Function.prototype
// Object.__proto__ => Function.prototype
Object instanceof Function; // true
// Object做为构造函数继承自Function.prototype,Function.prototype__proto__指向Object.prototype
// Object.__proto__ => Function.prototype => Function.prototype.__proto__ => Object.prototype
Object instanceof Object; // true
// Function构造函数也是继承自Function.prototype
// Function.__proto__ => Function.prototype
Function instanceof Function; // true
复制代码
总结一下:先有 Object.prototype
(原型链顶端),Function.prototype
继承 Object.prototype
而产生,最后,Function
和 Object
和其它构造函数继承 Function.prototype
而产生。
Object.prototype
是浏览器底层根据 ECMAScript
规范创造的一个对象。Function.prototype
直接继承的Object.prototype
,一样它也是由是引擎建立出来的函数,引擎认为不须要给这个函数对象添加 prototype
属性。Function.prototype.prototype
为undefined
。Object.prototype
(原型链顶端),Function.prototype
继承 Object.prototype
而产生,最后,Function
和 Object
和其它构造函数继承 Function.prototype
而产生。