11-原型对象


11-原型对象

我们在学习构造函数那一节的时候遇到了一个问题。

 1 

大家看这个,咱们可以发现虽然可以达到创建多个对象,只调用一次函数的效果,但是也有许多弊端。

将函数定义在全局作用域,污染全局作用域的命名空间,而且定义在全局作用域中也很不安全。因为一个程序一般都是多个人参与开发的,另外一个开发人员可能会用到和你一样的函数名,这样就会污染变量。
下面就为大家介绍另外一种方法:原型对象法

首先为大家解释什么是原型对象?

在每一个构造函数对象中都有一个隐藏的属性prototype,而这个属性是一个对象,我们把这个对象称作原型对象。

大家可以看下面这段代码:

1         function Dog(){
2             console.log("一只小狗");
3         }
4         console.log(Dog.prototype);

这段代码运行效果如下:

既然prototype是一个对象那他就可以拥有自己的属性和方法,大家可以看下面这张图:

 另外,这个属性在同一个构造函数中创建的对象中是一样的:

1         function Dog(){
2             console.log("一只小狗");
3         }
4         // console.log(Dog.prototype);
5         d1 = new Dog();
6         d2 = new Dog();
7         console.log(d1.__proto__ === d2.__proto__);
8         console.log(d1.__proto__ === Dog.prototype);

这段代码运行效果如下:

 基于以上特性我们可以将需要在构造函数中使用的属性、方法,全部放到原型属性里面:

(原型对象就像是一个公共的区域,所有同一类的实例都可以访问到这个原型对象。)

 1         function Person(name, age, sex){
 2             this.name = name;
 3             this.age = age;
 4             this.sex = sex;
 5         }
 6         Person.prototype.sayName = function(){
 7             console.log(`大家好,我是${this.name},我是${this.sex}生,我${this.age}岁`);
 8         }
 9         obj1 = new Person("孙悟空", 10000, "男");
10         obj1.sayName();

下图是上面代码执行效果:

 在JS中当我们访问对象的一个属性或者方法时,他会现在对象自身中寻找,如果有则直接使用,如果没有就向原型对象中找。

另外原型对象也是一个对象,是一个对象就有原型对象,那么是不是没有尽头呢?我们来看下面的代码:

1         console.log(d1.__proto__);
2         console.log(d1.__proto__.__proto__);
3         console.log(d1.__proto__.__proto__.__proto__);  // 返回空

下图是代码执行效果:

 通过上面代码我们发现并不是所有对象都有原型对象,那么哪一类对象没有原型对象呢?

Object对象没有原型对象,如果在Object中依然没有找到,则返回null或undefined