前言
- JavaScript中的
Object是构造函数(创建对象的包装器) - 构造函数,通过prototype来存储要共享的属性和方法,也可以设置prototype指向现存的对象来继承该对象。
Object.getPrototypeOf(Object)和Object.prototype不一样Object.getPrototypeOf()方法返回指定对象的原型(内部[[Prototype]]属性的值)Object.getPrototypeOf(Object)等同于Object.__proto__([[prototype]] === __proto__)
内容
Object, Function, 和 new Object()
测试
console.log(Object) // ƒ Object() { [native code] }
console.log(Object.prototype) // {constructor: ƒ, __defineGetter__: ƒ, …}
console.log(Object.prototype.constructor === Object)// true
console.log(typeof Object.prototype) // "object"
console.log(Object.getPrototypeOf(Object)) // ƒ () { [native code] }
console.log(Object.__proto__) // ƒ () { [native code] }
console.log(Object.getPrototypeOf(Object.prototype))// null
console.log(Function) // ƒ Function() { [native code] }
console.log(Function.prototype) // ƒ () { [native code] }
console.log(Object.getPrototypeOf(Function)) // ƒ () { [native code] }
console.log(typeof Function) // function
console.log(typeof Function.prototype) // function
console.log(Object.getPrototypeOf(Function) === Function.prototype) // true
console.log(Object.getPrototypeOf(Function) === Object.getPrototypeOf(Object)) // true
console.log(Function == Object) // false
let obj = new Object(); // 等同于 let obj = {}
console.log(obj) // {} 展开后有 [[Prototype]]: Object
console.log(typeof obj) // "object"
console.log(obj.prototype) // undefined
console.log(Object.getPrototypeOf(obj)) // {constructor: ƒ, __defineGetter__: ƒ, …}
console.log(typeof(Object.getPrototypeOf(obj))) // "object"
console.log(Object.getPrototypeOf(Function.prototype)) //{constructor: ƒ, …}
解析
- 单独的
Object是一个Object类型的构造函数,它有一个与之关联的 Object.prototype 对象 可以通过调用Object.prototype来访问 - Object.prototype 对象中存储着所有共享的方法和属性,并且还有一个
constructor属性等于 Object 构造函数 - Object.prototype 对象的原型对象
[[prototype]](也称__proto__,但不推荐使用) 是原型链的终点,值为null - Object的原型对象
[[prototype]](也称__proto__) 等于 Function 构造函数的原型对象[[prototype]]也等于 Function 构造函数的protytype - 单独的
Function是一个 Function 类型的构造函数 Function的Function.protytype和原型对象[[protytype]]是相等的,他们也都等于Object的原型对象[[prototype]](也称__proto__)
总结
Object.prototype.constructor === Object
Object.prototype.__proto__ === null
Object.__proto__ === Function.__proto__ == Function.prototype
实例,原型,和构造函数
测试
function fn() {
let x = 1;
this.y = 2;
console.log("In fn: ", this)
}
fn.prototype.z = 3;
console.log(fn) // f fn() {let x = 1; this.y = 2;}
console.log(fn.prototype) // {z: 3, constructor: ƒ} 展开后有 [[Prototype]]: Object
console.log(Object.getPrototypeOf(fn)) // ƒ () { [native code] }
let instance = new fn();
console.log(instance) // In fn: fn {y: 2} // fn {y: 2} 展开后有 [[Prototype]]: Object
console.log(instance.prototype) // undefined
console.log(Object.getPrototypeOf(instance)) // {z: 3, constructor: ƒ fn()} 展开后有 [[Prototype]]: Object
解析
在一般看来,当我们自定义一个函数fn后,如果直接用()调用这个函数,那么这个函数就作为一个普通函数;
如果用 new 操作符调用这个函数并赋值给一个变量,那么这个函数就是fn类型的构造函数,变量就是实例。
作为一个普通函数 fn :
- 它的第一层执行环境是包含他的对象,也就是
this是包含他的对象,如果这个函数是在全局中,那么就是 window 对象。 - 它也有一个与之关联的 fn.prototype 对象,通过
fn.prototype访问, - fn.prototype 对象可以加自定义方法和属性,它内部属性
constructor等于 fn 构造函数。 - fn.prototype 对象的原型对象
[[prototype]]就是Object - 它的原型对象
[[prototype]]等于 Object 的原型对象[[prototype]]
作为一个用 new 操作符调用的构造函数 fn ,对于它的实例 instance :
- 这个实例
instance的第一层执行环境就是当前构造函数本身, 也就是内部的 this 指向自己的构造函数内部 - 它也有一个与之关联的 fn.prototype 对象,通过
fn.prototype访问, - fn.prototype 对象可以加自定义方法和属性,它内部属性
constructor等于 fn 构造函数。 - fn.prototype 对象的原型对象
[[prototype]]就是Object - 它的原型对象
[[prototype]]等于Object的原型对象[[prototype]] instance实例的原型对象[[protytype]]等于 fn.prototype 对象instance实例的prototype是undefined
当用 new 操作符创建一个 Object 这个构造函数的实例的时候,这个实例的原型对象 [[prototype]] 等于 Object.prototype 对象。
这个实例没有自己的 protytype 属性
小结
fn.prototype.constructor === fn
fn.prototype.__proto__ = Object.prototype
fn.__proto__ === Object.__proto__
instance.__proto__ === fn.prototype
instance.__proto__.constructor === fn
instance.__proto__.__proto__ === Object.prototype
instance.__proto__.__proto__.__proto__ === null