下面是面向对象的一种写法—混合开发:构造函数+原型
私有的属性和方法写在构造函数中,公有的属性和方法写在原型中。
一、那么什么是原型?
原型(prototype):对象属性,每一个函数都有一个原型属性,里面放置的是公有的属性和方法,里面的this依然指向实例对象。
prototype用于保存构造函数实例的公有属性的。同时,prototype 中的所有属性都可以由实例对象访问到(语法: 实例对象 . 属性)。
因此,上述案例中打印的结果显示为true.
我们继续上面的案例,打印下console.log(Phone.prototype);
显示的结果:
可以看出:constructor 是 prototype 下的一个子属性。
继续执行下面的操作
显示的结果为:
由此可见,prototype 下的constructor属性是一个指针,它指向的是原型所在的函数。
二、那么我们再来深入了解下原型。
2.1首先思考一个问题:JS中的对象是哪来的?
我们会联想到 1.new关键字;2. JS中的是对象是由函数创建的
看下面的例子:
打印的结果:
1.所有的对象都有 __ proto__。
2.__ proto__ 是隐式原型,它的本质依旧是一个指针。
3.它指向的是该对象的构造函数的原型对象
指向示意图如下:
对象的属性查找:
1. 在对象自身查找 如果找到就使用
2. 沿__proto__ 向上查找 找到就使用
3. 整个__proto__ 结构都没有找到 返回 undefined
怎么理解呢?
拿上面的例子来说:如果要找寻foo实例化对象下的公有的abc属性,先找寻对象自身,发现没有;就沿该对象的__proto__向上查找,查找到该对象的构造函数的原型对象下有abc属性,就进行调用
继续瞧
foo实例化对象自身上没有toString()属性,沿__proto__向上寻找到Foo.prototype也没有to.String();
那么这结果又是怎么出来呢?
2.2思考 :原型这个对象又是谁创建的呢?
答案:原型对象是由Object创建的
画个链式图来解释:
查找toString()属性,沿__proto__ 向上查找,一直找到了Object的原型对象下toString()属性,找到就使用。
2.3那么继续思考:函数是由谁创建的?
答案:函数由函数的构造函数创建的
打印看一下Foo函数的构造函数的原型对象
仔细分析下图会对原型链有系统性的认识
原型链示例图:
对象下的属性都是按照原型链一级一级向上找寻的。
例如:foo对象自身先查找,向上查找Foo.prototype,再向上查找Object.prototype,再向上到null;按照原型链一级一级向上查找如果找寻不到,最终返回undefined
总结:所有的函数是由函数的构造函数创建的,所有的原型对象是由Object创建的