关于JS中prototype的理解


Posted in Javascript onSeptember 07, 2015

每一个构造函数都有一个属性叫做原型(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的理解,希望大家喜欢。

Javascript 相关文章推荐
javascript 特殊字符串
Feb 25 Javascript
jquery获取下拉列表的值为null的解决方法
Mar 18 Javascript
tangram框架响应式加载图片方法
Nov 21 Javascript
jQuery插件EasyUI校验规则 validatebox验证框
Nov 29 Javascript
JS获取浮动(float)元素的style.left值为空的快速解决办法
Feb 19 Javascript
使用原生js写ajax实例(推荐)
May 31 Javascript
Validform验证时可以为空否则按照指定格式验证
Oct 20 Javascript
Vue2.5通过json文件读取数据的方法
Feb 27 Javascript
vue源码nextTick使用及原理解析
Aug 13 Javascript
js实现烟花特效
Mar 02 Javascript
Openlayers实现图形绘制
Sep 28 Javascript
Javascript文本框脚本实现方法解析
Oct 30 Javascript
js+css实现超简洁的二级下拉菜单效果代码
Sep 07 #Javascript
jquery实现简单的二级导航下拉菜单效果
Sep 07 #Javascript
jQuery平滑旋转幻灯片特效代码分享
Sep 07 #Javascript
js调用百度地图及调用百度地图的搜索功能
Sep 07 #Javascript
js实现可折叠展开的手风琴菜单效果
Sep 07 #Javascript
原生JS实现美图瀑布流布局赏析
Sep 07 #Javascript
js实现全国省份城市级联下拉菜单效果代码
Sep 07 #Javascript
You might like
用Php实现链结人气统计
2006/10/09 PHP
php面向对象全攻略 (十二) 抽象方法和抽象类
2009/09/30 PHP
PHP中用正则表达式清除字符串的空白
2011/01/17 PHP
PHP数据库链接类(PDO+Access)实例分享
2013/12/05 PHP
教你在header中隐藏php的版本信息
2016/08/10 PHP
Laravel修改验证提示信息为中文的示例
2019/10/23 PHP
Prototype 1.5.0_rc1 及 Prototype 1.5.0 Pre0小抄本
2006/09/22 Javascript
javascript instanceof,typeof的区别
2010/03/24 Javascript
JQuery Dialog的内存泄露问题解决方法
2010/06/18 Javascript
密码强度检测效果实现原理与代码
2013/01/04 Javascript
javascript事件冒泡详解和捕获、阻止方法
2014/04/12 Javascript
在myeclipse中如何加入jquery代码提示功能
2014/06/03 Javascript
js中运算符&amp;&amp; 和 || 的使用记录
2014/08/21 Javascript
AspNet中使用JQuery上传插件Uploadify详解
2015/05/20 Javascript
JQuery包裹DOM节点的方法
2015/06/11 Javascript
在JavaScript中call()与apply()区别
2016/01/22 Javascript
jQuery EasyUI 入门必看
2016/06/03 Javascript
vue使用stompjs实现mqtt消息推送通知
2017/06/22 Javascript
基于jQuery实现Ajax验证用户名是否可用实例
2018/03/25 jQuery
vue使用自定义icon图标的方法
2018/05/14 Javascript
使用jquery模拟a标签的click事件无法实现跳转的解决
2018/12/04 jQuery
Python语言编写电脑时间自动同步小工具
2013/03/08 Python
Python下使用Psyco模块优化运行速度
2015/04/05 Python
详解Swift中属性的声明与作用
2016/06/30 Python
shell命令行,一键创建 python 模板文件脚本方法
2018/03/20 Python
如何在Cloud Studio上执行Python代码?
2019/08/09 Python
python安装mysql的依赖包mysql-python操作
2021/01/01 Python
uniapp+Html5端实现PC端适配
2020/07/15 HTML / CSS
客服实习的个人自我鉴定
2013/10/20 职场文书
中文专业毕业生自荐书范文
2014/01/04 职场文书
大学运动会入场词
2014/02/22 职场文书
医疗专业毕业生求职信
2014/08/28 职场文书
小学毕业典礼演讲稿
2014/09/09 职场文书
学校政风行风评议心得体会
2014/10/21 职场文书
检讨书大全
2015/01/27 职场文书
《合作意向书》怎么写?
2019/08/20 职场文书