您的位置:首页 > Web前端 > JavaScript

原型与原型链

2017-04-13 15:07 162 查看
javascript是唯一一个被广泛使用的基于原型继承的语言。

在JavaScript中,万物皆对象。

构造函数

function Person() { }

var person = new Person();
person.name = "张三"


我们创建一个
Person
构造函数,使用
new
来创建一个实例对象
person


prototype

为了解决构造函数的对象实例之间无法共享属性的缺点,JavaScript提供了
prototype
属性。
prototype
就是“一个给类的对象添加方法的方法”,使用prototype属性,可以给类动态地添加方法,以便在JavaScript中实现”继承”的效果。

JavaScript中每个对象都有
prototype
属性,它本身也是对象,JavaScript中对象的
prototype
属性的解释是:返回对象类型原型的引用。

function Person() {}
Person.prototype.name="张三";
var person1 = new Person();
var person2 = new Person();

console.log(person1.name); // 张三
console.log(person2.name); // 张三


上例中,将
name
属性放在
prototype
中,两个实例
person1
person2
都共享同一个属性。

对于构造函数来说,
prototype
是作为构造函数的属性;对于对象实例来说,
prototype
是对象实例的原型对象,所以
prototype
既是属性又是对象。


什么是原型?

每一个JavaScript对象(除null、undefined外)在创建的时候就会与之关联另一个对象,这个对象就是我们说的原型,每一个对象都会从原型"继承"属性。




__proto

每个对象(除null、undefined)都会在其内部初始化一个属性,就是
__proto__
,这个属性会指向对象的原型。

__proto__
是不对外公开的,是个私有属性,但是Firefox和Chrome的引擎将其暴露出来成为一个公共属性,我们可以对外访问和设置。所以我们可以使用
Object.getPrototypeOf(obj)
代替
__proto__


function Person() {}
var person = new Person();
console.log(person.__proto__ === Person.prototype); // true




constructor

constructor
属性, 构造函数,始终指向创建当前对象的构造函数。

每个函数都有一个
prototype
属性,而
constructor
prototype
的属性,即对象实例的属性, 而
prototype
是函数的属性。

function Person() {}
var person = new Person();
console.log(Person === Person.prototype.constructor); // true
console.log(person.constructor === Person); // true


说明: 当获取
person.constructor
时, 其实
person
中并没有
constructor
属性, 当不能读取到
constructor
属性时,会从
person
的原型也就是
Person.prototype
中读取,正好原型中有该属性。所以
person.constructor === Person.prototype.constructor




__proto__
prototype
cosntructor
之间的联系:

function Person() {}
var person1 = new Person();
console.log(person1.__proto__ === Person.prototype); // true
console.log(Person === Person.prototype.constructor); // true
console.log(Object.getPrototypeOf(person1) === Person.prototype); // true


实例与原型

当读取实例的属性时, 如果找不到,就会查找与对象关联的额原型中的属性,如果还查不到,就去原型的原型,一直找到最顶层位置。

function Person() {}
Person.prototype.name = '张三';
var person = new Person();
person.name = '李四';
console.log(person.name); // 李四
delete person.name;
console.log(person.name); // 张三


这个例子中,我们设置了
person
中的
name
属性,所以我们读取到“李四”, 当我们删除了
person
name
属性时,读取
person.name
, 从
person
中找不到就会从
person
的原型也就是
person.__proto__ === Person.prototype
中查找,哎,发现找到了
name
, 则输出”张三”。 如果没有找到呢?原型的原型又是什么?

使用最原始的方式创建:

var obj = new Object();
obj.name = '张三';
console.log(obj.name);


所以原型对象是通过
Object
构造函数生成的, 所以….



原型链

原型链并不是无限长,也有尽头—–
null




图中由相互关联的原型组成的链状结构就是原型链,也就是蓝色的路线。

end

继承意味着复制操作,然而JavaScript默认并不会复制对象的属性,相反,JavaScript只是在两个对象之间创建一个关联,这样,一个对象就可以通过委托访问另一个对象的属性和函数,所以与其叫继承,委托的说法反而更准确些。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息