前置知识
- 所有的对象,它都有__proto__和constructor属性。
- 所有的函数,它所特有的“prototype”属性,同时函数也是对象,也具有__proto__属性。
- 所有的对象,它的__proto__属性指向它的构造函数的“prototype”属性。
- __proto__是隐式原型,prototype是显式原型,它们都是普通的对象。
- 任何函数都可作为构造函数,只有当函数通过new关键字调用的时候才可以成为构造函数。
构造函数实例化对象
function farther(){}
var mother = function(){}
//声明、定义一个函数,那它只是一个普通的函数,下面我们让这个函数变得不普通
var son = new Mother();
//这时这个Mother就不是普通的函数了,它现在是一个构造函数。因为通过new关键字调用了它
//创建了一个Mother构造函数的实例son
小结
new fn() 中 new关键字后面跟函数,是一个表达式(运算符) 创建对象的运算,整个表达式一定会得到 一个对象,下面是实现步骤。
- 创建一个空对象。
- 运行构造函数,让内部的this指向创建的对象(用创建的空对象去调用构造函数)。
- 整个表达式的结果看函数的返回值。
- 返回值是引用数据 那么就是返回值。
- 返回值不是引用数据 那么就是这个运行完毕之后的创建的那个对象。
prototype属性
prototype是对象的原型,属性prototype是在函数作为构造函数时使用,创建出来的对象的原型对象就是prototye属性引用的对象(系统内置的对象:new Object())。由这个构造函数创建的任何对象都会继承属性prototype引用的对象的所有属性。
__proto__属性
它是对象所独有的,可以看到__proto__属性都是由一个对象指向一个对象,即指向它们的原型对象(也可以理解为父对象),__proto__属性的作用就是当访问一个对象的属性时,如果该对象内部不存在这个属性,那么就会去它的__proto__属性所指向的那个对象(父对象)里找,一直找,直到__proto__属性的终点null,再往上找就相当于在null上取值,会报错。通过__proto__属性将对象连接起来的这条链路即我们所谓的原型链。
原型
原型的总结:
- 所有引用类型都有一个
__proto__(隐式原型)属性,属性值是一个普通的对象。 - 所有函数都有一个prototype(原型)属性,属性值是一个普通的对象。
- 所有引用类型的
__proto__属性指向它构造函数的prototype。 - 所有函数的
__proto__都是指向Function的prototype。 - 构造函数new出来的对象
__proto__指向构造函数的prototype。 - 非构造函数实例化出的对象或者对象的prototype的
__proto__指向Object的prototype。
- 函数的原型prototype:函数才有prototype,prototype是一个对象,指向了当前构造函数的引用地址。
- 对象的
__proto__属性:所有对象都有__proto__属性, 当用构造函数实例化(new)一个对象时,会将新对象的__proto__属性指向构造函数的prototype(成为对象的原型对象)。
原型链
原型链是原型对象创建过程的历史记录,当访问一个对象的某个属性时,会先在这个对象本身属性上查找,如果没有找到,则会去它的__proto__隐式原型上查找,即它的构造函数的prototype,如果还没有找到就会再在构造函数的prototype的__proto__中查找,这样一层一层向上查找就会形成一个链式结构。