JS 中的 phototype 是 JS 中比较难理解的一个部分。javascript 的方法可以分为三类:类方法,对象方法,原型方法。
例子:
- function People(name) {
- this.name = name;
- //对象方法
- this.Introduce = function() {
- alert("My name is " + this.name);
- }
- }
- //类方法
- People.Run = function() {
- alert("I can run");
- }
- //原型方法
- People.prototype.IntroduceChinese = function() {
- alert("我的名字是" + this.name);
- }
- //测试
- var p1 = new People("Windking");
- p1.Introduce();
- People.Run();
- p1.IntroduceChinese();
obj1.func.call(obj) 方法意思是将 obj 看成 obj1,调用 func 方法。
javascript 中的每个对象都有 prototype 属性,Javascript 中对象的 prototype 属性的解释是:返回对象类型原型的引用。
- A.prototype = new B();
理解 prototype 不应把它和继承混淆。A 的 prototype 为 B 的一个实例,可以理解 A 将 B 中的方法和属性全部克隆了一遍。A 能使用 B 的方法和属性。这里强调的是克隆而不是继承。可以出现这种情况:A 的 prototype 是 B 的实例,同时 B 的 prototype 也是 A 的实例。
先看一个实验的例子:
- function baseClass()
- {
- this.showMsg = function()
- {
- alert("baseClass::showMsg");
- }
- }
- function extendClass()
- {
- }
- extendClass.prototype = new baseClass();
- instance = new extendClass();
- instance.showMsg(); // 显示baseClass::showMsg
我们首先定义了 baseClass 类,然后我们要定义 extentClass,但是我们打算以 baseClass 的一个实例为原型,来克隆的 extendClass 也同时包含 showMsg 这个对象方法。extendClass.prototype = new baseClass() 就可以阅读为:extendClass 是以 baseClass 的一个实例为原型克隆创建的。
那么就会有一个问题,如果 extendClass 中本身包含有一个与 baseClass 的方法同名的方法会怎么样?
下面是扩展实验 2:
- function baseClass()
- {
- this.showMsg = function()
- {
- alert("baseClass::showMsg");
- }
- }
- function extendClass()
- {
- this.showMsg =function ()
- {
- alert("extendClass::showMsg");
- }
- }
- extendClass.prototype = new baseClass();
- instance = new extendClass();
- instance.showMsg();//显示extendClass::showMsg
实验证明:函数运行时会先去本体的函数中去找,如果找到则运行,找不到则去 prototype 中寻找函数。或者可以理解为 prototype 不会克隆同名函数。
那么又会有一个新的问题:如果我想使用 extendClass 的一个实例 instance 调用 baseClass 的对象方法 showMsg 怎么办?
答案是可以使用 call:
- extendClass.prototype = new baseClass();
- instance = new extendClass();
- var baseinstance = new baseClass();
- baseinstance.showMsg.call(instance);//显示baseClass::showMsg
这里的 baseinstance.showMsg.call(instance); 阅读为 "将 instance 当做 baseinstance 来调用,调用它的对象方法 showMsg"。好了,这里可能有人会问,为什么不用 baseClass.showMsg.call(instance); 这就是对象方法和类方法的区别,我们想调用的是 baseClass 的对象方法
最后,下面这个代码如果理解清晰,那么这篇文章说的就已经理解了:
- <script type="text/javascript">
- function baseClass()
- {
- this.showMsg = function()
- {
- alert("baseClass::showMsg");
- }
- this.baseShowMsg = function()
- {
- alert("baseClass::baseShowMsg");
- }
- }
- baseClass.showMsg = function()
- {
- alert("baseClass::showMsg static");
- }
- function extendClass()
- {
- this.showMsg =function ()
- {
- alert("extendClass::showMsg");
- }
- }
- extendClass.showMsg = function()
- {
- alert("extendClass::showMsg static")
- }
- extendClass.prototype = new baseClass();
- instance = new extendClass();
- instance.showMsg(); //显示extendClass::showMsg
- instance.baseShowMsg(); //显示baseClass::baseShowMsg
- instance.showMsg(); //显示extendClass::showMsg
- baseClass.showMsg.call(instance);//显示baseClass::showMsg static
- var baseinstance = new baseClass();
- baseinstance.showMsg.call(instance);//显示baseClass::showMsg
- </script>
来源: http://it.taocms.org/08/4625.htm