JS--面向对象之原型模式创建对象

前言:我们创建的每个函数都有一个prototype属性,这个属性是一个指针,指向的是一个对象,这个对象的作用是包含由该构造函数创建实例共享的属性和方法。通过字面意思来了解,prototype是通过构造函数创建对象实例的原型对象,使用原型对象的好处就是可以让所有的实例共享它所包含的属性和方法,这样就不会像构造函数模式,在每次创建一个新的实例后都会将内部的方法重新创建一遍。如下例子图1-1:


JS--面向对象之原型模式创建对象_第1张图片
图 1-1

我们可以看到在Person构造函数的prototype原型上面我们挂载了属性和方法,我们在创建实例的时候,每个实例都会有相同的属性和方法,与构造函数模式不同的是这些属性和实例都是共享的。

什么是原型对象?

在我们创建每一个函数的时候,都会根据特定的规则为该函数创建一个prototype属性,这个属性指向的是函数的原型对象。在每个函数的prototype属性下面也会自动获得一个constructor(构造函数)属性。我们可以打印一下Person.prototype.constructor,如下2-1:


图 2-1

创建自定义的构造函数后,其原型对象只会去得到constructor属性,其他的方法都是从Object上继承来的。当调用构造函数创建一个对象的时候,这个对象内部将会有个一指针指向的是构造函数的原型对象上,我们管这个指正叫做[[Prototype]],在chrome等浏览器中打印出来显示的是__proto__,我们要知道这个是连接实例对象和构造函数原型对象的。如图3-1和3-2:


JS--面向对象之原型模式创建对象_第2张图片
图3-1



JS--面向对象之原型模式创建对象_第3张图片
图3-2

我们可以看到上图中,实例对象的__proto__打印的是构造函数的原型对象,原型对象上也有一个constructor属性,指向的是构造函数。

这里我们介绍两个方法:isPrototypeOf()  /  Object.getPrototypeOf(),根据英文的意思,第一个就是判断某个原型对象是不是某个实例[[Prototype]]指向的原型对象,第二个是用来获得某个实例对象的原型对象。如下图代码4-1和4-2:


JS--面向对象之原型模式创建对象_第4张图片
图 4-1


JS--面向对象之原型模式创建对象_第5张图片
图 4-2

之前我们不是说通过原型构造对象,所有的对象共享原型对象上的方法和属性么,那么这是怎么共享的呢?当我们要读取某个实例对象上的某个属性或者方法的时候,它会在当前的对象上进行搜索,如果找到了那么就返回这个属性或者方法,如果没有找到,就会搜索指针指向的原型对象,在该原型对象上找到的话就会返回这个原型对象上的属性值和方法....就这样会一直找到Object对象上。那么反过来理解,如果我们在实例对象上新增一个同原型对象上一样的name属性,那么当读取该name属性的时候,就会读取到当前实例对象上为止,就不会继续往上读取了。

这里我们再次介绍一个方法:hasOwnProperty(),该方法可以检测一个属性是否存在于实例中,还是存在于原型中(该方法继承于Object)。如图5-1例子:


JS--面向对象之原型模式创建对象_第6张图片
图 5-1

如例子所示,hasOwnproperty方法是是用来判断属性或者方法是不是实例属性方法还是原型上的属性方法。

这个我们抛出一个问题,如何定义一个属性是在实例对象上的还是在原型对象上的?那么我们要通过in操作符hasOwnProperty()方法一起来判断了,in操作符可以在for-in循环中使用,也可以单独使用,单独使用的时候,如果某个属性在实例对象上或者原型对象上都返回TRUE,根据之前的例子可以知道,hasOwnProperty()方法只会在属性在实例上的时候才返回TRUE,那么当操作符in返回TRUE的时候,hasOwnproperty()返回FALSE的时候,可以判断当前属性是在原型对象上的,而不是在实例对象上的。

有些困了,今天就复习到这里,明天进一步更新,更多的内容可以看js高级程序设计....

你可能感兴趣的:(JS--面向对象之原型模式创建对象)