prototype属性初探

Javascript是面向对象的语言,但是它没有“子类”和“父类”的概念,它的继承靠“原型链(prototype chain)”来实现。


首先从 JavaScript 创建实例说起

我定义了一个构造函数

function Cat(name){
    this.name = name;
}

并生成两个实例

var cat1 = new Cat('小黑');
var cat2 = new Cat('小白');

这个时候 cat1 和 cat2 都继承了 Cat 的 name/age 属性

console.log(cat1.name);//小黑
console.log(cat2.name);//小白

但是如果我想要定义一个公共属性呢,譬如说使这两个实例的种类都是‘猫’,那么

function Cat(name){
    this.species = '宠物猫';
    this.name = name;
}
var cat1 = new Cat('小黑');
var cat2 = new Cat('白猫');
console.log(cat1.name,cat1.species);//小黑 宠物猫
console.log(cat2.name,cat2.species);//小白 宠物猫

这样小黑和小白在出生的时候就species属性就都是 '宠物猫' 了。

然而,有一天人们发现 Cat 这个构造函数的species属性描述并不准确(不潮流),'宠物猫' 应该变成 '猫主子'。

于是我修改了Cat 的属性

Cat.species = '猫主子';
console.log(Cat.species);//猫主子
console.log(cat1.species);//宠物猫
console.log(cat2.species);//宠物猫
cat1和cat2的属性还是宠物猫,所以我还要这样改
cat1.species = '猫主子';
cat2.species = '猫主子';
console.log(cat1.species);//猫主子
console.log(cat2.species);//猫主子

如果我有一百只宠物猫呢?...

有没有办法让 cat1 和 cat2 的属性自动随 Cat 属性变化呢,伟大的prototype来了。我们修改一下原代码

function Cat(name){
    this.name = name;
}
Cat.prototype.species = '宠物猫';
var cat1 = new Cat('小黑');
var cat2 = new Cat('白猫');
console.log(cat1.name,cat1.species);//小黑 宠物猫
console.log(cat2.name,cat2.species);//小白 宠物猫

这时候,只要改变构造函数的属性,实例属性也会自动变化

Cat.prototype.species = '猫主子';
console.log(Cat.species);//undefined
console.log(Cat.prototype.species);//猫主子
console.log(cat1.species);//猫主子
console.log(cat2.species);//猫主子

解释一下以上代码:

prototype 是构造函数(或者说函数)的一个特有的属性,这个属性值为一个对象,实例一旦创建,将自动引用构造函数 prototype 对象的属性和方法。

当 species 属性是未定义在  prototype 对象中时,实例相当于创建了自己独有的species 属性,其值在创建后不受构造函数的影响;

当 species 属性定义在  prototype 对象中时,实例相当于引用了prototype的species 属性,其值随prototype的改变而改变。

实例自己创建species属性后实例中species将不随 prototype 对象属性值改变:

如添加以下代码

cat1.species = '最喜欢的猫';
console.log(Cat.prototype.species);//猫主子
console.log(cat1.species);//最喜欢的猫
console.log(cat2.species);//猫主子
这是因为实例额的属性和方法,分为两种,一种是本地的,一种是引用的。当本地定义了species属性后,将会优先显示本地的属性值。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值