function A(){
this.a = '1';
this.b = '2';
this.init();
}
A.prototype.init = function(){
console.log('000000');
}
new A()
上面的这个可以输出000000,而下面这个就不行:
function A(){
this.a = '1';
this.b = '2';
this.init();
}
A.init = function(){
console.log('000000');
}
new A()
这是为什么呢?
Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号
使用new的时候大概就像这个样子:
(摘抄自《JavaScript语言精粹》)
也就是说,先从原型创建一个对象,然后调用构造函数的内容,你这里的话就是执行
这些内容
所以你直接给A加一个init函数是没用的。
prototype可以理解为一个Javascript类的各个对象全部共有的一个属性。通过prototype属性才能调用对象的属性或者方法。
A.init是一个类方法,A.prototype.init是一个成员方法! 类方法必须使用类才能调用!成员方法,只有实现出来的成员才能调用
prototype屬性是保存所有實例方法真正的所在,也就是說諸如toString(),valueOf()等方法實際都是保存在prototype名下。
第一種聲明的init,可以通過new聲明來繼承(偽),第二種不行,因為prototype裡面沒有。
你也可以按照語言精粹方式去理解,但是那不是真實的過程。
实在理解不了的话,我们可以换位思考。
new一个A的实例对象之后,他就继承了构造函数中所有对象都要实现的init方法。可是init在哪呢?构造函数中并没有定义函数体,那么重要的来了,他会沿着原型链往上找,找谁呢?找A.prototype对应的原型对象,看看它,有没有init方法,如果有,则调用,如果没有呢?很简单,继续A.prototype.prototype,以此类推,直到原型对象是null为止。那么真相来了?它有找A.init()这个方法吗?没有,所以,添加在构造函数上的方法,只有A能调用,属于私有的类方法和类变量,实例对象是无法调用的
因为init不在对象的原型链上。
A.prototype在对象的原型链上,而A不在对象的原型链上,所以如果将init定义在A上,对象是找不到的。定义在A.prototype上才能找到。
通过构造函数创建对象,会使用构造函数的prototype属性作为原型。而init不在prototype属性上,是不会继承的。
定义一个function(无论是构造函数还是普通函数),其实也是定义了一个对象(Function对象)。A.init就是给这个function对象定义了一个方法。
而在A里面调用this.init,调用的是另一个对象的方法(new出来的新对象)。
这是你原来的代码: 首先运行代码会出现错误,找不到init方法,为什么呢? 将
new A()对象打印出来就可以看到,其实init函数实际上是在constructor属性上的,并没有在prototype上所以找不到,也不在new A()对象的原型链上,所以使用this调用init就会出错