JS
中原型是一个很重要的知识点,正因为有了原型这个概念使得JS
中可以实现类似面向对象语言中的对象的继承。本篇文章主要介绍JS
中的原型,以及由原型衍生的原型链的概念和常见的使用场景。下图是有关原型和原型链之间的关系图,图是从网上找的足够大家去理解掌握,就没重新绘制了。
原型
在JS
中当我们创建一个函数的时候,语言本身就会自动为这个函数生成一个prototype
属性,而这个prototype
属性指向的就是这个函数创建的原型对象,默认情况下,所有原型对象自动获取一个名为constructor
的属性,指回与之关联的构造函数。我们可以通过下述代码来帮助理解:
function Person() {}
Person.prototype.name = 'Mr.Right';
Person.prototype.age = 22;
Person.prototype.job = 'Worker';
Person.prototype.sayName = function() {
alert(this.name);
}
var person1 = new Person();
person1.sayName(); // 'Mr.Right'
var person2 = new Person();
person2.sayName(); // 'Mr.Right'
console.log(person1.sayName == person2.sayName); //true
如上的代码所示,其中person1
、person2
就是原型对象,其中的name
、age
、sayName
都是prototype
指向荟原型对象的属性。原型对象中的属性调用需要通过函数的构造方式创建的实例对象才可调用,即new
关键字。原型对象类似于一个公共调用区域,所有的函数创建的实例共用一个原型对象。
原型链
每个实例对象即上述实例中的person1
、person2
,都会被创建一个__proto_
属性,该属性指向该对象的原型,其关系如下代码:person.__proto__ === Person.prototype
function Person() {
}
var person = new Person();
console.log(person.__proto__ === Person.prototype); // true
由此形成一个链状结构。如上原型对象本身也包含一个__proto__
属性,而__proto__
属性指向该原型实例对应的函数原型,图示结构如下:
注意:Object.prototype.__proto__
的值为 null
跟 Object.prototype
没有原型,所以查找属性的时候查到 Object.prototype
就可以停止查找了。
原型层级
当我们通过对象访问属性时,会按照属性的名称开始搜索,搜索顺序可以按照如下的优先级排序:
- 对象实例本身
- 原型对象
- 原型对象的原型