推荐阅读:https://blog.csdn.net/cc18868876837/article/details/81211729,作者:码飞_CC,讲的很详情,而且有图解
总结一下:
- 我们需要牢记两点:①
__proto__
和constructor
属性是对象所独有的;②prototype
属性是函数所独有的,因为函数也是一种对象,所以函数也拥有__proto__
和constructor
属性。 - __proto__属性的作用就是当访问一个对象的属性时,如果该对象内部不存在这个属性,那么就会去它的__proto__属性所指向的那个对象(父对象)里找,一直找,直到__proto__属性的终点null,然后返回undefined,再往上找就相当于在null上取值,会报错。通过__proto__属性将对象连接起来的这条链路即我们所谓的原型链。
prototype
属性的作用就是让该函数所实例化的对象们都可以找到公用的属性和方法,即f1.__proto__ === Foo.prototype
constructor
属性的含义就是指向该对象的构造函数,所有函数(此时看成对象了)最终的构造函数都指向Function
hasOwnProperty函数:
所有继承了 Object
的对象都会继承到 hasOwnProperty
方法。这个方法可以用来检测一个对象是否含有特定的自身属性;他能判断一个对象是否包含自定义属性而不是原型链上的属性,因为hasOwnProperty 是 JavaScript 中唯一一个处理属性但是不查找原型链的函数。
avaScript 不会保护 hasOwnProperty
被非法占用,因此如果一个对象碰巧存在这个属性, 就需要使用外部的 hasOwnProperty
函数来获取正确的结果。当检查对象上某个属性是否存在时,hasOwnProperty
是唯一可用的方法。 同时在使用 for in
loop 遍历对象时,推荐总是使用 hasOwnProperty
方法, 这将会避免原型对象扩展带来的干扰
// 修改 Object.prototype
Object.prototype.bar = 1;
var foo = {moo: 2};
for(var i in foo) {
//console.log(i); // 输出两个属性:bar 和 moo
if (foo.hasOwnProperty(i)) {
console.log(i);
}
}
/*
由于我们使用了 hasOwnProperty,所以这次只输出 moo。 如果不使用 hasOwnProperty,则这段代码在原生对象原型(比如 Object.prototype)被扩展时可能会出错
*/