原型:每个对象拥有一个原型对象,对象以其原型为模板、从原型继承方法和属性。
原型链:原型对象也有可能拥有原型,并从中继承方法和属性,一层一层、依此类推,这种关系常被称为原型链(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属性,该属性指向了用于构造此实例对象的构造函数。
1399

被折叠的 条评论
为什么被折叠?



