<script type="text/javascript">
function Person(name,age) {
this.name = name;
this.age = age;
}
Person.say = function(){
alert('Person的say');
}
Object.prototype.say = function(){
alert('Object原型的say');
}
Function.prototype.say = function(){
alert('Function原型的say');
}
Function.say = function(){
alert('Function的say');
}
Person.prototype.say = function() {
alert(this.name);
};
let p = new Person('月初',16);
p.say();
</script>
这个本站的demo
为什么弹出的是月初而不是“Person的say”,哪位帮忙解释下
这样去说在一个对象实例化之前,这个对象其实也就是一个函数
参照你的问题 为什么弹出的是 月初 而不是 “Person的say” ?
首先你要考虑一个问题,在对象没有被实例化之前,他只是一个首字母大写的函数,那如果给函数直接定义一个 .方法的话找的是谁?
万物不变起源 万物皆对象 抛去其他的一切因素 调用 Person.say() 寻找的层级先滤清 先找 Person.say -> Function.prototype.say -> Object.prototype.say, 你可以先这样去试一下
<script type="text/javascript">
function Person(name, age) {
this.name = name;
this.age = age;
}
Object.prototype.say = function () {
alert("Object原型的say");
};
Function.prototype.say = function () {
alert("Function原型的say");
};
Function.say = function () {
alert("Function的say");
};
Person.prototype.say = function () {
alert(this.name);
};
// Person.say = function () {
// alert("Person的say");
// };
// let p = new Person("月初", 16);
Person.say(); // 寻找层级 Person.say -> Function.prototype.say -> Object.prototype.say
</script>
而如果你的对象实例化之后,这个时候其实他已经被new了,那么他就不再会是一个函数,而是一个对象,如果没有父实例,那么他的上级指向将不再会是 Function,参照下方
<script type="text/javascript">
function Person(name,age) {
this.name = name;
this.age = age;
}
Object.prototype.say = function(){
alert('Object原型的say');
}
Function.prototype.say = function(){
alert('Function原型的say');
}
Function.say = function(){
alert('Function的say');
}
// Person.prototype.say = function() {
// alert(this.name);
// };
Person.say = function(){
alert('Person的say');
}
let p = new Person('月初',16);
p.say(); // alert('Object原型的say');
</script>
</html>
简单的说 Person.prototype.say != Person.say 一个是在其对象原型上挂载say方法,一个是在其方法上挂载一个say方法,而原型链查找的是 prototype 所以会出现你所说的找不到的问题
Person.say类似于oo语言的静态方法,需要通过类名称来调用,而不是实例。
Person.prototype.say则是实例方法,p为实例,所以p.save()输出月初。
要输出Person的say,应该是Person.say()
实例-构造函数-原型
,p - Person - Person.prototype
,原型链说的是实例会共享对应原型上的方法,因此p.say访问的是Person.prototype.say而不是Person.say。new Function()
来的,因此它的构造函数肯定是Function,同样的也可以理解为三层,实例-构造函数-原型
,Person - Function - Function.prototype
,因此Person.say()原本应该
会alert出Function原型的say
,但是由于你对Person.say赋值,可以理解为重写了,因此输出的是Person的say
,你不妨把Person.say重写的部分删掉,你就看见输出它原型Funtcion的say了。原型
本身是个对象,因此它是Object的实例,也可以用三层的方式理解,你可以随便用一个原型,比如p.prototype(或者Person.prototype或者Funtion.prototype) - Object - Object.prototype
。