js中.__proto__既然是存在于内置的 Object.prototype 中不存在与对象中为啥console.log能打印出来?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了js中.__proto__既然是存在于内置的 Object.prototype 中不存在与对象中为啥console.log能打印出来?相关的知识,希望对你有一定的参考价值。
.__proto__ 实际上并不存在于你正在使用的对象中 (本例中是 a)。实际上,它和其他的常用函数(.toString()、.isPrototypeOf(..),等等)一样,存在于内置的 Object.prototype 中。(它们是不可枚举的,参见第 2 章。) 此外,.__proto__ 看起来很像一个属性,但是实际上它更像一个 getter/setter(参见第 3 章)。 .__proto__ 的实现大致上是这样的(对象属性的定义参见第 3 章): Object.defineProperty( Object.prototype, "__proto__", get: function()
return Object.getPrototypeOf( this ); ,set: function(o) // ES6 中的 setPrototypeOf(..) Object.setPrototypeOf( this, o );
return o; ); 因此,访问(获取值)a.__proto__ 时,实际上是调用了 a.__proto__()(调用 getter 函 数)。
又没人帮忙释疑
就好比说,你new一个字符串(String)对象,这个新生成的对象中只存在一个length属性,但你一样可以对这个对象使用replace、trim、split等字符串操作方法,因为他们是存在于String对象中,所有子对象都可以直接调用(看起来就跟子对象本身具有的属性和方法一样)追问
.__proto__属性不是每个对象都带的一个内部属性吗?为什么说是存在于
内置的 Object.prototype
中
你是在哪看到说__proto__“是每个对象都带的一个内部属性”呢?是浏览器控制台吗?那是控制台为了方便你查看,直接从原型对象中提取出来当作这个对象的属性的,因为从表象来看,__proto__确实和对象内部属性几乎完全一样,但它确实不存在于对象中。
其实你也可以这样来理解:如果通过一个对象来创建一个新对象,完全没有必要把原对象的所有属性和方法都复制到新对象中,新对象只需要到原对象中调用这些属性和方法即可,否则的话,如果需要生成很多个子对象,将会大大浪费内存资源。这其实就是共性和个性的问题,把所有共性都放在原型对象中,子对象只需要保留个性即可,也就是有别于其他子对象的属性和方法。这才是最有效的方法。
那总得有一个属性指向上一级的原型吧,如果对象没有原型这个属性的话怎么实现原型链的形式
参考技术A 和继承一个意思js原型继承
function对象结构(Persion)
Persion{
eat:f()
__proto__:Object{
constructor:
}
}
_proto__ 属性,它是对象所独有的
__proto__属性都是由一个对象指向一个对象,即指向它们的原型对象
它的作用就是当访问一个对象的属性时,如果该对象内部不存在这个属性,
那么就会去它的__proto__属性所指向的那个对象里找,如果父对象也不存在这个属性,
则继续往父对象的__proto__属性所指向的那个对象里找,如果还没找到,
则继续往上找…直到原型链顶端null,此时若还没找到,则返回undefined
prototype属性 它是函数所独有的,它是从一个函数指向一个对象。它的含义是函数的原型对象,
也就是这个函数(其实所有函数都可以作为构造函数)所创建的实例的原型对象
prototype属性 作用就是包含可以由特定类型的所有实例共享的属性和方法,
也就是让该函数所实例化的对象们都可以找到公用的属性和方法。任何函数在创建的时候,
其实会默认同时创建该函数的prototype对象
p.proto === Persion.prototype,它们两个完全一样
总结:
1、我们需要牢记两点:①__proto__和constructor属性是对象所独有的;
② prototype属性是函数所独有的,因为函数也是一种对象,所以函数也拥有__proto__和constructor属性。
2、__proto__属性的作用就是当访问一个对象的属性时,如果该对象内部不存在这个属性,
那么就会去它的__proto__属性所指向的那个对象(父对象)里找,一直找,直到__proto__属性的终点null,
然后返回undefined,通过__proto__属性将对象连接起来的这条链路即我们所谓的原型链。
3、prototype属性的作用就是让该函数所实例化的对象们都可以找到公用的属性和方法,
即p.__proto__ === Persion.prototype。
4、constructor属性的含义就是指向该对象的构造函数,所有函数(此时看成对象了)最终的构造函数都指向Function
代码:
//function继承
function inherits(Child, Parent) {
var F = function() { };
F.prototype = Parent.prototype;
Child.prototype = new F();//修改子类prototype指向
//任何一个prototype对象都有一个constructor属性,指向它的构造函数
//由于修改了child prototype为F则对应的constructor会指向F的prototype的constructor(也就指向了Parent的构造函数了),
//所以要对应设置一个prototype的contructor
Child.prototype.constructor = Child;
Child.super = Parent.prototype;//设置super属性,方便调用父类的prototype方法
}
以上是关于js中.__proto__既然是存在于内置的 Object.prototype 中不存在与对象中为啥console.log能打印出来?的主要内容,如果未能解决你的问题,请参考以下文章
对象&内置对象& 对象构造 &JSON&__proto__和prototype