问题来源于这里:
<script>
function Human(){
this.height =180;
this.say =function(){
alert("我在说话");
}
}
var he=newHuman();
alert(Human.prototype); // Object
alert(he.prototype); // undefined
</script>
为什么 Human.prototype 是存在的,而 he.prototype 却是 undefined?
其实说起来比较简单。
prototype 是函数对象用于构造实例时使用的一个属性。也就是说,我们通常关注的是构造函数的 prototype,而通过构造函数创建出来的实例对象,并不会因此自动拥有一个同名的 prototype 属性。
所以 Human.prototype 存在,而 he.prototype 不存在。
这也就是之前文章中第一个没有弄明白的问题。
JavaScript 中的构造器
为了彻底弄明白 JavaScript 的继承机制,我们再来看一下 JavaScript 中的一些内置构造器。
常见的有:
- Object
- Number
- Boolean
- String
- Array
- RegExp
- Date
- Function
- Error
另外还有 Math、JSON 等内置对象。
其中 Math 和 JSON 本身就是对象,并不是通过 new 来创建实例的构造器。
例如 var mm=new Math(1234565); 这种写法就是错误的。
这时候又会产生一个问题。
我们平时定义字符串、数字、对象的时候,并没有总是使用 new,例如:
var str="This is a String";
或者:
var book= {
name: "Javascript",
page: 168
};为什么这样也可以?
这里其实涉及 JavaScript 中的原始值、对象以及包装对象等机制。由于和今天要讲的问题关系不大,这里暂时不展开。
那么哪些对象具有 prototype 属性?
这里需要特别注意:
prototype是函数对象上的属性,用于原型继承和构造实例。
例如:
function Human(){
}
alert(Human.prototype);
可以访问到 Human.prototype。
但是:
var he=new Human();
alert(he.prototype);
//则是 undefined
//类似地:
var str="I am a String Object";
alert(str.prototype);
//结果同样是 undefined因为这里的 str 是一个字符串值,并不是构造函数。
所以,理解这个问题最重要的一点就是:
不要把
prototype理解成“所有 JavaScript 对象都有的属性”。它主要存在于函数对象上,并作为构造函数创建实例时使用的原型对象。
这也就解释了为什么:
前面的文章已经提到 he.__proto__ ===Human.prototype
实例对象真正关联的是它的原型,而不是拥有一个自己的 prototype 属性。
评论0
欢迎分享你的看法,也欢迎补充不同的实践经验。