原型链是面向对象的一个基础,也可以说是一个基石,如果原型链不能理解,那么不能说是熟悉JavaScript
创建对象有几种方法
字面量对象
var o1 = {name:'01'}
其实下面这种方式不是字面量,但是这里给归为一类,也可以把下面的方式理解为构造函数的方式
var o11 = new Object({name:'o11'})
使用显示的构造函数来创建对象
var M = function(){this.name = 'o2'}
var o2 = new M()
使用Object.create
使用Object.create这种方法创建对象是使用原型链方式来链接这个对象的
var P = {name:'o3'}
var o3 = Object.create(P)
创建对象的代码
<body>
<script>
//第一种方式:字面量
val o1 = {name:'o1'}
var o2 = new Object({name:'o2'})
//第二种方式:通过构造函数
var M = function(name){this.name=name}
var o3 = new M('o3')
//第三种方式:Object.create
var p = {name:'p'}
var o4=Object.create(p)
</script>
</body>
原型、构造函数、实例、原型链
1、任何一个函数只要是被new使用了,后面这个函数就可以是叫构造函数;构造函数是可以使用new运算符来生成一个实例
2、任何函数都可以用来当做构造函数,只要使用new来操作立马就成了构造函数,不使用new就还是一个普通函数
3、函数都有一个prototype属性,是在声明一个函数的时候,JavaScript自动给加上的一个属性,这个prototype就是原型对象,也就是说,在声明一个函数的时候,JavaScript引擎给构造函数自动增加一个属性,这个属性就是构造函数的prototype,
它会初始化一个空对象,也就是我们说的原型对象
4、原型对象怎么区分被哪个构造函数引用呢?
原型对象中有一个构造器constructor,这个构造器会默认声明的那个函数
构造函数的原型对象通过constructor和构造函数保持关联
5、原型链
原型链就是说从一个实例对象往上找构造这个实例相关联的对象,然后这个对象在往上找,还有创造它的原型对象,一次类推,一直到Object.prototype终止,
也就是说Object.prototype是整个原型链的顶端,到那就截止了
6、原型链是通过什么实现向上找的这个过程呢?
其实就是通过prototype原型和__proto__这个属性实现原型链的查找的
7、原型对象和原型链之间到底起了什么样的作用?
构造函数中增加了很多属性和方法,那么实例中就可以共用这些属性和方法,当多个实例的时候,想要公用这个方法的时候,不能每个实例都拷贝一份,当都需要这些属性或者方法的时候,
可以考虑存储到一个共同的东西上面,这个共同的东西就是原型对象;
通过原型链的方式找到原型对象,原型对象的方法是被不同实例所共有的,这个就是原型链的工作原理
当访问一个实例的时候,如果在实例本身上没有找到这个方法或者属性的时候,就会往上级原型对象上去查找,如果上一级原型对象没有这个属性或者方法,会在原型对象的基础上再通过原型对象的__proto__再往上一级查找,以此类推,直到找到了Object.prototype
如果到这还没找到,那么会原路放回,告诉这个方法或者属性没有没有找到没有定义,如果在中间任何地方找到了,那么会停止向上查找原路返回。
强调一下:
第一点构造函数也就是函数才会有prototype,对象是没有的。
第二点只有实例对象有__proto__,如果有人疑问说函数也有__proto__,原因是既是函数它也是一个对象,所以他也会有这个属性,它的这个属性是什么呢
instanceof原理
就是来判断实例对象的属性和构造函数的属性判断是不是同一个引用
new运算符
一个新对象被创建。它继承自foo.prototype
V
构造函数foo被执行。执行的时候,相应的传参会被传入,同时上下文(this)会被指定为这个新实例。new foo等同于new foo(),只能用在不传递任何参数的情况下
V
如果构造函数返回了一个对象,那么这个对象会取代整个new出来的结果。如果构造函数没有返回对象,那么new出来的结果为步骤1创建的对象。