原型链
原型链
- 原型对象 prototype; 隐式对象/原型proto; 可以理解为实例化后的变量才有原型,而其创建类是有原型对象属性
- Object 具有原型对象和隐式对象.并且其隐式对象是指向 Function.prototype
- Function 具有原型对象和隐式对象,其原型对象和隐式对象是全等的 Function.prototype === Function.proto
- 使用 function 创建的构造函数,其原型对象指向此类,隐式对象指向 Function
- ps:
- 只有实例化对象才有proto属性.
- JS 中的函数可以作为函数使用,也可以作为类使用
- Object.proto === Function.prototype ===Function.protot;Function.prototype.proto === Object.prototype;
- 作为类使用的函数实例化时需要使用 new
- 为了让函数具有类的功能,函数都具有 prototype 属性。
- 为了让实例化出来的对象能够访问到 prototype 上的属性和方法,实例对象的proto指向了类的 prototype。所以 prototype 是函数的属性,不是对象 的。对象拥有的是proto,是用来查找 prototype 的。
- prototype.constructor 指向的是构造函数,也就是类函数本身。改变这个指针并不能改变构造函数。
- 对象本身并没有 constructor 属性,你访问到的是原型链上的 prototype.constructor。
- 函数本身也是对象,也具有proto,他指向的是 JS 内置对象 Function 的原型 Function.prototype。所以你才能调用 func.call,func.apply 这些方 法,你调用的其实是 Function.prototype.call 和 Function.prototype.apply。
- prototype 本身也是对象,所以他也有proto,指向了他父级的 prototype.proto和 prototype 的这种链式指向构成了 JS 的原型链。原型链的最 终指向是 Object 的原型。Object 上面原型链是 null,即 Object.prototype.proto === null。
- 另外评论区有朋友提到:Function.proto === Function.prototype。这是因为 JS 中所有函数的原型都是 Function.prototype,也就是说所有函数都是 Function 的实例。Function 本身也是可以作为函数使用的----Function(),所以他也是 Function 的一个实例。类似的还有 Object,Array 等,他们也可以作为函数使用:Object(), Array()。所以他们本身的原型也是 Function.prototype,即 Object.proto === Function.prototype。换句话说,这些可 以 new 的内置对象其实都是一个类,就像我们的 Puppy 类一样。
- ES6 的 class 其实是函数类的一种语法糖,书写起来更清晰,但原理是一样的。