原型与原型链

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 中,两个实例person1person2 都共享同一个属性。

对于构造函数来说,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 属性,而constructorprototype 的属性,即对象实例的属性, 而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__prototypecosntructor 之间的联系:

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 属性,所以我们读取到“李四”, 当我们删除了personname 属性时,读取person.name, 从person 中找不到就会从person 的原型也就是person.__proto__ === Person.prototype 中查找,哎,发现找到了name, 则输出”张三”。 如果没有找到呢?原型的原型又是什么?

使用最原始的方式创建:

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

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

这里写图片描述

原型链

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

这里写图片描述

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

end

继承意味着复制操作,然而JavaScript默认并不会复制对象的属性,相反,JavaScript只是在两个对象之间创建一个关联,这样,一个对象就可以通过委托访问另一个对象的属性和函数,所以与其叫继承,委托的说法反而更准确些。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值