速记:
g.__proto__ === Object.getPrototypeOf(g) === Graph.prototype
F.prototype.constructor === F
Object.prototype.__proto__ === null // true
Function
console.log(Function.prototype) // function() {} (一个空的函数)
console.log(typeof Function.prototype.prototype) //undefined
Function.prototype.__proto__ === Object.prototype
详细笔记:
-
另一种角度:JavaScript 世界万物诞生记
prototype
是用于类型的,而Object.getPrototypeOf()
【用于访问__proto__
】 是用于实例的function Graph() { this.vertexes = []; this.edges = []; } Graph.prototype = { addVertex: function(v){ this.vertexes.push(v); } }; /* 以下两种实例化方式,原型链相同, ** constructor都是Object() { [native code] }【因为重写了Graph.prototype】, ** 【确切的说,g.constructor 不是自身的属性,而是从 g.__proto__(即Graph.prototype,也就是一个字面量对象)上面取得的constructor,也就是Object】, ** 但是第一种没有vertexes和edges属性 **/ // g = Object.create(Graph.prototype); var g = new Graph(); // g.__proto__ === Object.getPrototypeOf(g) === Graph.prototype
-
- 每个对象都有
__proto__
属性(指向创建其构造函数的原型对象),但只有函数对象才有prototype
属性(指向函数的原型对象) prototype
- 在默认情况下,所有的原型对象都会自动获得一个
constructor
(构造函数)属性,这个属性(是一个指针)指向prototype
属性所在的函数(F.prototype.constructor === F
) - 原型对象(
Person.prototype
)是构造函数(Person
)的一个实例。 - 原型对象其实就是普通对象(
Function.prototype
除外,它是函数对象(Function
的实例),没有prototype属性)
- 在默认情况下,所有的原型对象都会自动获得一个
console.log(Function.prototype) // function() {} (一个空的函数) console.log(typeof Function.prototype) // Function,这个特殊 console.log(typeof Function.prototype.prototype) //undefined
__proto__
- 所有函数对象的
__proto__
都指向Function.prototype
,它是一个空函数(Empty function) - 内置(build-in)构造器:Number、Boolean、String、Object、Function、Array、RegExp、Error、Date 均为函数对象
- 所有函数对象的
typeof Number.prototype // 'object' Number.__proto__ === Function.prototype // true Number.constructor == Function //true
- Math,JSON是以对象形式存在的,无需new。它们的`__proto__`是`Object.prototype`
Math.__proto__ === Object.prototype // true Math.construrctor == Object // true
Function.prototype.__proto__ === Object.prototype
(所有的构造器也都是一个普通 JS 对象)Object.prototype.__proto__ === null // true
- js 的继承靠的是__proto__ ,并不是prototype
var animal = function(){}; var dog = function(){}; animal.price = 2000; dog.prototype = animal; var tidy = new dog(); console.log(dog.price) //undefined console.log(tidy.price) // 2000
- 每个对象都有
var F=function(){};
Object.prototype.a=function(){};
Function.prototype .b=function(){};
var f=new F();
// f.constructor === F.prototype.constructor === F
// Object F[的构造函数] === (F.prototype)[的构造函数] === Function
// f.__proto__ === f[的构造函数].prototype === F.prototype
// F.prototype.__proto__ === (F.prototype)[的构造函数].prototype === Object.prototype (所以a能够通过f.a访问)
// F.__proto__ === F[的构造函数].prototype === Function.prototype (所以b可以通过f.constructor.b访问到)
var o;
// 创建一个原型为null的空对象
o = Object.create(null);
o = {};
// 以字面量方式创建的空对象就相当于:
o = Object.create(Object.prototype);
function Constructor(){}
o = new Constructor();
// 上面的一句就相当于:
o = Object.create(Constructor.prototype);
// 当然,如果在Constructor函数中有一些初始化代码,Object.create不能执行那些代码
// 创建一个以另一个空对象为原型,且拥有一个属性p的对象
o = Object.create({}, { p: { value: 42 } })
// 省略了的属性特性默认为false,所以属性p是不可写,不可枚举,不可配置的: