原型对象的定义
prototype显式原型
每一个构造函数,都会被解析器添加一个属性prototype
(显式原型属性),这个属性默认指向着一个Object
对象,这个对象就称为原型对象。
function Student()
{
}
console.log("Student.prototype的数据类型为:",typeof(Student.prototype));
console.log(Student.prototype);

__proto__隐式原型
当函数作为构造函数函数调用prototype
时,它所创建的对象中都有一个隐含的属性,指向该构造函数的原型对象,我们可以通过__proto__
(隐式原型属性)来访问。
function Student()
{
}
var stu1 = new Student();
var stu2 = new Student();
var stu3 = new Student();
console.log(stu1.__proto__ === Student.prototype);
console.log(stu2.__proto__ === Student.prototype);
console.log(stu3.__proto__ === Student.prototype);

所以实例指向大概就如下图所示

原型对象就相当于一个公共的区域,所有同一个类的实例,都可以访问到这个原型对象,可以将对象中共有的内容统一设置到原型对象中。
一般是添加属性(方法),作用:所有的实例对象自动拥有原型中的属性(方法)
例如:
Student.prototype.a = 10;
Student.prototype.show = function()
{
alert("人生大舞台,谁用谁精彩!!!");
}
console.log(Student.prototype);

这样就成功添加进去,并且每个实例对象都可以访问
console.log(stu1.a);
console.log(stu2.a);
console.log(stu3.a);
console.log(stu1.show());

大概如下图所示

- 当我们访问一个对象实例的属性或方法时,它会优先在对象自身中寻找,如果有则直接使用,如果没有则会去原型对象寻找,如果找到则直接使用。
stu1.a = 250;
console.log(stu1.a);
console.log(stu2.a);
console.log(stu3.a);

constructor属性
原型对象中有一个属性constructor,它指向函数对象
console.log(Student.prototype.constructor === Student);

一个完整的逻辑图

原型链
原型对象也是对象,那么它是不是也有原型呢?
所以举个例子:
console.log(stu1.__proto__.__proto__);

答案也是有原型的,而且其中还有两个常用的方法,也就是说很多常用但是不需要我们自己定义的方法例如toStrint()
和hasOwnProperty()
就放在这个原型当中,这个对象就是Object
的原型对象。
hasOwnProperty()
方法可以用来检查对象自身是否含有该属性,只有当对象自身含有属性时,才会返回true。
语法:
hasOwnProperty("属性名")
那么如果我们再往这个原型对象,检查是否还有原型呢?
console.log(stu1.__proto__.__proto__.__proto__);

答案是null
也就是说在往Object
的原型对象上面就没有原型了。故此,原型链的尽头就是Object函数的原型对象。
所以我们可以将上面的图更新为:

如何查找对象属性(方法)
访问一个对象属性时:
- 先从自身属性中查找,找到返回
- 如果没有,在沿着·
__proto__
这条链向上查找,找到返回
- 如果最终没找到,返回
undefined
- 故此原型链也叫隐式原型链
- 可以理解为:
- 如果没有在自身找到,就去原型的对象中寻找,如果原型对象中有,则使用。
- 如果没有则去原型的原型中寻找,直到找到Object对象的原型
- 如果
Object对象
的原型中仍然没有,就返回undefined
。
例如在stu1
实例自身中创建一个test1
:
function Student()
{
}
var stu1 = new Student();
stu1.test1 = function()
{
console.log("我是自己的方法!");
}
stu1.test1();

然后再往Student()
的原型里面添加一个test2
function Student()
{
}
var stu1 = new Student();
Student.prototype.test2 = function()
{
console.log("我是Student原型中的方法!");
};
stu1.test2();

如果里面没有任何地方都没有test3
,则会报undefined
function Student()
{
}
var stu1 = new Student();
Student.prototype.test2 = function()
{
console.log("我是Student原型中的方法!");
};
console.log(stu1.test3);

故此查找对象属性(方法)大概如图所示:
