JavaScript的原型和原型链

原型

JavaScript 原型是构造函数所构造对象的模板。

例如:

function Person(name,age,sex){
    this.name = name;
    this.age = age;
    this.sex = sex;
}
Person.prototype.hair = 'black';
Person.prototype.skin = 'yellow';

var person = new Person('Cheney',23,'male');

那么person为

可以看到person具有的显式属性只有name,age,sex,那如果我们访问person.skin和person.hair会怎么样呢?

由于person自身没有设置hair和skin属性,那么访问时系统就会查找它的原型中的属性。

我们可以这样理解,prototype是DNA,其中有这个种族共有的特性,比如我们的黑头发黄皮肤是刻在DNA中的,不需要后期赋值就具有的属性。

在查看person时,我们发现它有一个__proto__属性,在chrome控制台呈浅粉色,访问它

这种以双下划线开头和结尾的变量一般为系统赋予的隐式变量,即系统不希望被修改的属性(当然,如果你想修改,它也没办法)。

__proto__指向了构造函数的原型,即构造这个对象的模板

实际上在构造函数中,系统隐式地添加了这一句

this.__proto__ = Person.prototype;

person.__proto__和Person.prototype指向同一块内存,而那块内存保存着模板信息,即

this.__proto__ = Person.prototype = {
    hair: 'black',
    skin: 'yellow'
}

至此,我们知道,构造函数的prototype为一个对象,这个对象保存着构造新对象时所用的模板信息,在构造新对象时,系统隐式地给对象赋予一个__proto__属性,并将构造函数的prototype的值传给它(传递的是上面代码中对象的地址)。访问生成的新对象的属性时,会优先访问该对象自己的属性值,如果该对象没有这个属性,就查找__proto__中的属性。

*************************************************************************************************************************************************

以下为题目,供理解参考

// Q1
function Person(name,age,sex){
    this.name = name;
    this.age = age;
    this.sex = sex;
    this.__proto__ = Person.prototype;
  }
Person.prototype.hair = 'black';
Person.prototype.skin = 'yellow';

var person = new Person('Cheney',23,'male');
Person.prototype.hair = 'yellow';
console.log(person.hair);
// A1: yellow

/********分割线,以下代码与以上代码无关********/

// Q2
function Person(name,age,sex){
    this.name = name;
    this.age = age;
    this.sex = sex;
    this.__proto__ = Person.prototype;
  }
Person.prototype.hair = 'black';
Person.prototype.skin = 'yellow';

var person = new Person('Cheney',23,'male');
Person.prototype = {
    hair: yellow
}
console.log(person.hair);
// A2: black
/********分割线,以下代码与以上代码无关********/

// Q3
function Person(name,age,sex){
    this.name = name;
    this.age = age;
    this.sex = sex;
    this.__proto__ = Person.prototype;
  }
Person.prototype.hair = 'black';
Person.prototype.skin = 'yellow';
Person.prototype = {
    hair: yellow
}
var person = new Person('Cheney',23,'male');

console.log(person.hair);
// A3: yellow

*注意prototype传递给__proto__为地址传递,即可解决以上问题

 

原型链

接下来谈一下原型链。

Grand.prototype.lastName = "Smith";
function Grand(){}
var grand = new Grand();

Father.prototype = grand;
function Father(){}
var father = new Father();

Son.prototype = father;
function Son(){}
var son = new Son();

console.log(son.lastName);;

执行以上的语句

我们说过,访问生成的新对象的属性时,会优先访问该对象自己的属性值,如果该对象没有这个属性,就查找__proto__中的属性。

son自己的属性里找不到lastName,就去son.__proto__里找,即father,而father的属性中也找不到lastName,那么继续向上,转向father.__proto__中查找,同理......最后终于在grand.__proto__中找到,这样原型连成链的结构称为原型链。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值