js中先有Function,还是先有Object?
「这是我参与2022首次更文挑战的第7天,活动详情查看:2022首次更文挑战」
Function 和 Object 的微妙关系
在 JavaScript 中存在着两个关系很微妙的类,那就是 Function 和 Object,为什么说他们的关系微妙? 因为 Function instanceof Object
和 Object instanceof Function
的值同时为 true
instanceof
instanceof运算符用于测试构造函数的prototype属性是否出现在对象的原型链中的任何位置
Function
Function 构造函数 创建一个新的Function对象。在 JavaScript 中, 每个函数实际上都是一个Function对象。
Object
Object 构造函数创建一个对象包装器。Object构造函数为给定值创建一个对象包装器。如果给定值是 null 或 undefined,将会创建并返回一个空对象,否则,将返回一个与给定值对应类型的对象。 当以非构造函数形式被调用时,Object 等同于 new Object()。
Object.prototype.constructor
返回创建实例对象的 Object 构造函数的引用。注意,此属性的值是对函数本身的引用,而不是一个包含函数名称的字符串。对原始类型来说,如1,true和"test",该值只可读。
也就是说他们的原型链上相互包含对方,要知道原型链间接的描述了对象之间的继承关系。
如果 Object 在 Function 的原型链上,则可以认为 Object 是 Function 的实例。
Object 是一个类或者构造函数,所以说他是一个函数的实例很合理
但是同时 Function instanceof Object
也为 true,着表面 Object 也在 Function 的原型链上,那么也可以说 Function 是 Object 是实例。
万物皆对象,这好像也没有问题
但是他们到底谁才是谁的实例?谁先诞生的呢?这无疑是一个先有鸡还是先有蛋的问题。
但是下面的代码好像在告诉我们,Function 不是 Object 的实例对象,而是 Function 本身的实例
Function.constructor === Object //false
Function.constructor === Function //true
Object.constructor === Function //true
但是事实是什么呢?
起源
盘古开天辟地,js 中并不是就有了 Object
,而是 Object.prototype
。
js 中的万物(原始值
除外)都是继承自 Object
,唯独一个对象例外,那就是 Object.prototype
。
Object instanceof Object; //true
Object.prototype instanceof Object; // false
JS 中没有类,当我们说一个变量是另一个变量的实例时,我们在说什么?( instanceof 比较的是什么?)
借助 Object.create
我们有以下的栗子:
var p = {test:1}
var obj = Object.create(p)
function A(){}
obj instanceof A //false
A.prototype = p
obj instanceof A //true
当我们说一个对象继承自某个 Constructor 时,其实我们是在说,从这个对象的原型链上找到了 Constructor.prototype。
所以,Object.prototype 可以先于 Object 出现,然后用这个 prototype 构造出 Function.prototype,有了 Function.prototype 再构造出 Function , Object 这几个构造器。然后把 Object.prototype 挂到 Object 上,Function.prototype 挂到Function 上。
好比栗子中的 obj 构造自 p ,而 obj 构造出来之后,p 才挂到 A 上,我们说 obj 是 A 类型的,但是 obj 是用 A.prototype(就是 p ) 构造出来的。
分析可得:全局下的 Object 构造自 Function.prototype, Function.prototype 构造自 Object.prototype。
Object.getPrototypeOf(Object) === Function.prototype //全等哦
Object.getPrototypeOf(Function.prototype) === Object.prototype //全等哦
所以,是先有的 Object.prototype,再有的 Function.prototype ,再有的 Function 和 Object。
伪代码大致是这样,create 元操作的含义是使用给定的对象作为原型构造一个新的对象。
let ObjectPrototype = create( ); // C++开天辟地
let FunctionPrototype = create( ObjectPrototype );
//FunctionPrototype(后被赋值给了Function.prototype)是Object类型的
//因为其原型是ObjectPrototype
let Function = create( FunctionPrototype );
Function.prototype = FunctionPrototype;
// Function是Function类型的,也是Object类型的
//言外之意,Function对象 原型链上有Function.prototype和Object.prototype
Object = create( FunctionPrototype );
Object.prototype = ObjectPrototype;
//Object是Function类型的,也是Object类型的
//言外之意Object对象的原型链上有Function.prototype和Object.prototype
当然,在构造 Function 的时候远没有那么简单,这里只是简单解释了一下 Object 和 Function 之间错综复杂的关系。
转载自:https://juejin.cn/post/7057544558057357348