JavaScript中的原型

原型:每个对象拥有一个原型对象,对象以其原型为模板、从原型继承方法和属性。

原型链:原型对象也有可能拥有原型,并从中继承方法和属性,一层一层、依此类推,这种关系常被称为原型链(prototype chain),它解释了为何一个对象会拥有定义在其他对象中的属性和方法。

继承的属性和方法来源:定义在Object的构造函数之上的propotype属性上,而非对象实例本身。对象实例和它的构造器之间建立一个链接__proto__属性,是从构造函数prototype属性派生的。

如下:

function myFunction() {
    return 'hello world!'
};

在JavaScript中,函数可以有属性,每个函数都有一个特殊的属性叫作prototype(原型),获取函数默认的原型属性的两种方式:

1.

Object.getPrototypeOf(new myFunction())

输出:

{
constructor:ƒ myFunction(),
__proto__:{
    constructor:ƒ Object(),
    hasOwnProperty:ƒ hasOwnProperty(),
    isPrototypeOf:ƒ isPrototypeOf(),
    propertyIsEnumerable:ƒ propertyIsEnumerable(),
    toLocaleString:ƒ toLocaleString(),
    toString:ƒ toString(),
    valueOf:ƒ valueOf(),
    __defineGetter__:ƒ __defineGetter__(),
    __defineSetter__:ƒ __defineSetter__(),
    __lookupGetter__:ƒ __lookupGetter__(),
    __lookupSetter__:ƒ __lookupSetter__(),
    get __proto__:ƒ __proto__(),
    set __proto__:ƒ __proto__(),
}
}

2.

myFunction.prototype

输出:

{
constructor:ƒ myFunction(),
__proto__:{
    constructor:ƒ Object(),
    hasOwnProperty:ƒ hasOwnProperty(),
    isPrototypeOf:ƒ isPrototypeOf(),
    propertyIsEnumerable:ƒ propertyIsEnumerable(),
    toLocaleString:ƒ toLocaleString(),
    toString:ƒ toString(),
    valueOf:ƒ valueOf(),
    __defineGetter__:ƒ __defineGetter__(),
    __defineSetter__:ƒ __defineSetter__(),
    __lookupGetter__:ƒ __lookupGetter__(),
    __lookupSetter__:ƒ __lookupSetter__(),
    get __proto__:ƒ __proto__(),
    set __proto__:ƒ __proto__(),
}
}

区别:前者是每个实例上都有的属性,后者是构造函数的属性。

共同点:都指向同一个对象。

接下来创建一个对象:

var myfuncion_2 = new myFunction();

 

执行:

myfuncion_2

 

输出:

__proto__:{
constructor:ƒ myFunction(),6
__proto__:{
    constructor:ƒ myFunction(),
    __proto__:Object
}
}

 

为这个对象添加上一些属性:

myfuncion_2.age = 12;

 

输出:

{age:12,
__proto__:{
    constructor:ƒ myFunction(),
    __proto__:Object
}
}

 

可以看到上面的myfuncion_2 的__proto__属性就是myFunction.prototype.这个作用在于当访问myfuncion_2 的属性的时候,浏览器首先查找myfuncion_2 是否有这个属性,如果myfuncion_2 没有这个属性,浏览器就会在myfuncion_2 的__proto__中查找这个属性,也就是在myFunction中查找,如果在myFunction还是没找到,浏览器将会去找myFunction的__proto__中查找否有这个属性。而myFunction的__proto__就是window.Object.prototype,当找到这一层的时候,没找到,那么原型链上面的所有__proto__都被找完了,浏览器所有声明的__proto__上都不存在这个属性,这个属性就是undefined。

 

如:

//age是myfuncion_2自己的属性
myfuncion_2.age // 12 
/**在myfuncion_2中没有name这个属性,会去找myFunction中的,然而myFunction中也没有,
** 就会去找myFunction的__proto__,也就是window.Object.prototype,而window.Object.prototype也没有,当找到这一步的时候原型链
** 已经结束了,就返回undefined了。
**/
myfuncion_2.name  // undefined 

 

prototype和__proto__的区别 : __proto__是每一个对象实例(被new出来的实例)必有的,如上面的myfuncion_2。prototype是每一个构造器都拥有的属性,如myFunction有一个属性叫做prototype(原型)。本质上构造器的属性prototype对象就是实例对象中的__proto__,只是实例对象被建立后从构造器上继承这个对象,被叫为__proto__属性。

prototype:继承成员被定义的地方

constructor属性:每个实例对象都从原型中继承了一个constructor属性,该属性指向了用于构造此实例对象的构造函数。

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值