最近在学习js继承,学习了prototype属性。说实话,一直都很晕。不知道为啥,在我的理解中总感觉每个js对象都有prototype属性,可是写代码的时候发现实例化出来的对象的prototype属性却是undefined。代码如下:
var Person = function(){ }
var person = new Person();
alert(person.prototype); // undefined
<strong>代码证明通过new实例化出来的对象是没有prototype属性的,undefined就是答案。</strong>
其实官方资料是这么说的:JavaScript手册上说,所有 JavaScript<strong>内部对象</strong>都有只读的 prototype 属性。所以new出来的对象是我们自定义的扩展出来的,所以就没有prototype属性了吧。
但是在做继承的时候很多教材或者前辈分享的时候都会说要获取到当前对象的prototype属性,理论上不存在的属性怎么能获取呢?我想,这应该是一个概念的偷换或者是一个简略的说法吧。他们想表达的应该是获取实例化出来的对象的构造函数的对象(本人也是初学,不知道以上几个概念名词拼凑的是否准确)。以上的例子表示就是person的prototype属性应该就是Person的prototype属性。这一点可以用getPrototypeOf()方法证明:
alert(Object.getPrototypeOf(person)== Person.prototype); //true
不过person的prototype等于Person的prototype的这种说法是不正确的,正确的说法应该是person的prototype属性指向于Person的prototype属性。
接下来做一些其他测试吧,便于理解prototype,__proto__和getPrototypeOf。
alert(person.__proto__== Person.prototype);//true
可以看出__proto__跟Object.getPrototypeOf效果是等价的,不信就直接做对比
alert(person.__proto__== Object.getPrototypeOf(person));//true
alert(person.__proto__== Person.__proto__); //false
可以看出prototype跟__proto__是不同的。__proto__更像是指向上一级的prototype属性。 JS是这样定义的:在创建对象(不论是普通对象还是函数对象)的时候,都有一个叫做__proto__的内置属性,用于指向创建它的函数对象的原型对象prototype。猜测不错的话,Person.__proto__应该等于Function.prototype。
alert(Person.__proto__== Function.prototype); //true
因为js的内部对象中,Object,Number,Boolean,String,Array,RegExp,Date,Function,Error的原型是Function.prototype。而Math和JSON对象的原型是Object.prototype。
那再往上找应该就是到头了。
写到这的时候我以为我掌握js原型链了(别告诉我你也一样。。。),其实不然。js的原型链是__proto__串起来的直到Object.prototype.__proto__为null的链叫做原型链。如下图:
这样来说以上有个部分存在误导,就是alert(Person.__proto__== Function.prototype); //true
因为原型链是***.prototype.__proto__穿起来的链,而不是***.__proto__。
Person.__proto__== Function.prototype是正确的,但Person.__proto__不是原型链中的一环。Person.prototype.__proto__才是。Person.prototype.__proto__==Object.prototype。Object.prototype.__proto__为null。原型链到此结束。
未经允许不得转载:前端撸码笔记 » 探讨:javascript是不是每个对象都有prototype属性以及原型链解析