在 js 中 phototype 是 JS 中比较难理解的一个部分,下面通过本篇文章给大家介绍 js 中的 prototype,需要的朋友可以参考下
Javascript 是一种由 Netscape 的 LiveScript 发展而来的原型化继承的基于对象的动态类型的区分大小写的客户端脚本语言,主要目的是为了解决服务器端语言,比如 Perl,遗留的速度问题,为客户提供更流畅的浏览效果。
每一个构造函数都有一个属性叫做原型 (prototype)。这个属性非常有用:为一个特定类声明通用的变量或者函数。
prototype 的定义
你不需要显式地声明一个 prototype 属性,因为在每一个构造函数中都有它的存在
本文基于下面几个知识点:
1 原型法设计模式
在. Net 中可以使用 clone() 来实现原型法
原型法的主要思想是,现在有 1 个类 A, 我想要创建一个类 B, 这个类是以 A 为原型的, 并且能进行扩展。我们称 B 的原型为 A。
2 javascript 的方法可以分为三类:
a 类方法
b 对象方法
c 原型方法
例子:
- 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();
3 obj1.func.call(obj) 方法
意思是将 obj 看成 obj1, 调用 func 方法
好了,下面一个一个问题解决:
prototype 是什么含义?
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();
- var 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();
- var instance = new extendClass();
- instance.showMsg();//显示extendClass::showMsg
实验证明:函数运行时会先去本体的函数中去找,如果找到则运行,找不到则去 prototype 中寻找函数。或者可以理解为 prototype 不会克隆同名函数。
那么又会有一个新的问题:
如果我想使用 extendClass 的一个实例 instance 调用 baseClass 的对象方法 showMsg 怎么办?
答案是可以使用 call:
- extendClass.prototype = new baseClass();
- var 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();
- var 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>
以上内容是关于 JS 中 prototype 的理解,希望大家喜欢。
来源: http://www.phperz.com/article/17/0222/269477.html