对js原型的一些理解

个人感悟

  1. 构造器函数的constructor等于其本身
1
console.log(Function.constructor === Function); // true
  1. 某一构造器的实例,其constructor指向该构造器(从实例的角度来看可以理解为指向上一级的构造器)
1
2
3
4
5
6
7
function foo() {
this.name = "xxf";
}

var f1 = new foo();

console.log(f1.constructor === foo); // true
  1. 只有自身能充当构造器的才会有prototype

  2. 只要是函数(包括匿名函数)都可以做构造器

1
2
3
4
5
6
7
8
var fun = new Function();
var fun1 = new fun(); // fun1为一个普通对象,而非函数对象

console.log(fun1); // anonymous {}
console.log(fun); // [Function: anonymous]
console.log(fun1.constructor === fun); // true
console.log(fun1.prototype); // undefined
// fun1 为函数的实例对象,所以并不具有prototype

需要注意的是new Function()直接返回匿名函数对象(而非匿名函数的实例!),所以与直接赋值为匿名函数完全不同(直接赋值匿名函数相当于构造了一个函数对象的实例!):

1
2
3
4
5
6
7
var fun = function () {

}; // 相当于 function fun(){},但是没有函数声明提升!!!
var fun1 = new fun();

console.log(fun); // [Function: fun]
console.log(fun1); // fun {}
  1. Object实例对象constructor[Function: Object]
1
console.log({}.constructor); // [Function: Object]
  1. 只要是原型(prototype),其constructor必然指向下一级(即若该原型为Object实例对象,其constructor并不会指向[Function: Object]

  2. 某个对象原型(prototype)的constructor等于该对象本身

1
2
3
4
5
6
var fun = new Function();

console.log(fun.prototype); // anonymous {}
console.log(typeof fun.prototype); // object
console.log(fun.prototype.constructor); // [Function: anonymous]
console.log(fun.prototype.constructor === fun); // true
  1. 属性__proto__指的是上一级构造器prototype
1
2
3
4
5
var fun = new Function();

console.log(fun.prototype); // anonymous {}
console.log(fun.prototype.__proto__); // {}
console.log(fun.prototype.__proto__.constructor); // [Function: Object]

从上面的例字可以看出funprototye确实是object类型的,但是直接使用construcor并不能得到想要的结果,通过使用属性__proto__就能准确得到上一级构造器的原型

个人总结

关系图

参考文档

  1. js中__proto__和prototype的区别和关系? - 苏墨橘的回答 - 知乎