原型是什么
原型是一个对象,只有函数对象,才拥有指向原型的属性prototype。
函数对象是什么
在javascript中,对象分为两种,一种是普通对象,一种是函数对象。
函数对象包括javascript内置的,还有由内置对象Function声明的,除了这些外,其他的都是普通对象。
在浏览器的javascript中,总共有12个内置对象
其中包括9个函数对象:Number、String、Boolean、Function、Object、Date、RegExp、Error、Array。
还有3个特殊对象:Math和JSON是普通对象形式,可以直接调用;Arguments仅在调用时由js创建。
Function声明的
// 函数式声明
function Person(){}
// 函数表达式声明
const Person = function(){}
// 实例化Function对象声明
const Person = new Function('name,age', 'console.log(name,age)')
// 其实函数式声明和表达式声明都是由实例化Function而来的
prototype
函数对象在创建时,js会自动将prototype属性添加到当前函数对象上,prototype指向这个函数对象的原型对象。
原型对象创建时也会获得一个对象:constructor,并指向当前函数对象。
function Person(){}
Person.prototype.constructor === Person // true
__proto__
所有对象在创建时都会获得__proto__内置属性,这个属性指向创建它的构造函数的原型对象。
const obj = {}
obj.__proto__ === Object.prototype // true
构造函数
当任意一个函数对象用于创造一类对象的时候,就称它为构造函数
构造函数被实例化时:
- 创建一个空对象(实例函数)
- 实例函数的 __proto__属性指向构造函数的prototype。
- 将构造函数的作用域赋值给实例函数,然后调用构造函数,构造函数中用this声明的属性和方法会被声明到实例函数上
实例函数的constructor指向构造函数。
构造函数的prototype的constructor属性也指向构造函数。
function CO(name) {
this.name = name;
}
CO.prototype = {
getName: function() {
console.log(this.name);
}
}
// 构造函数实例化
var co = new CO('co');
// 相当于
var obj = {};
obj.__proto__ = CO.prototype;
CO.call(co)
obj.constructor = CO
原型链是什么
每一个对象创建时,会得到一个 __proto__属性,并且 __proto__属性指向构造函数的原型对象。
当访问对象的属性或方法时,如果当前对象没有这个属性或者方法,js便会去 __proto__属性下寻找,依次类推,直到__proto__ === null
时才会停止查找。
function A(name){
this.name = name
}
A.prototype = {
getName: function() {
return this.name
}
}
var a = new A('a')
a.getName() // a
a.__proto__ === A.prototype // true
a.constructor === A // true
A.prototype.constructor === A // true
结论/总结
以下结果均为true
// 构造函数由内置对象的函数对象的生成
A.__proto__ === Function.prototype
// 原型对象都指向内置对象中的对象的原型
Function.prototype.__proto__ === Object.prototype
A.prototype.__proto__ === Object.prototype
// 内置对象中的对象的原型的原型链指向null
Object.prototype.__proto__ === null
// 非常有意思的是,内置对象的函数对象指向它自己本身,也是Function
Function.constructor === Function
Object.constructor === Function
Array.constructor === Function
String.constructor === Function
// ...
// 所有的原型对象都是构造函数的一个实例对象
Function.prototype.constructor === Function
Array.prototype.constructor === Array
Object.prototype.constructor === Object
String.prototype.constructor === String
// ...
// 但是Function.prototype 比较特殊,new Function()得到的是一个函数对象, 所以Function.prototype 是一个函数对象
typeof Function.prototype // 'function'
typeof String.prototype // 'object'
typeof Array.prototype // 'object'
// ...