关于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 相关文章推荐
在jQuery中 关于json空对象筛选替换
Apr 15 Javascript
如何让DIV可编辑、可拖动示例代码
Sep 18 Javascript
对于Form表单reset方法的新认识
Mar 05 Javascript
yarn与npm的命令行小结
Oct 20 Javascript
任意Json转成无序列表的方法示例
Dec 09 Javascript
深入理解Node.js中通用基础设计模式
Sep 19 Javascript
jQuery实现的两种简单弹窗效果示例
Apr 18 jQuery
让webpack+vue-cil项目不再自动打开浏览器的方法
Sep 27 Javascript
详解vue使用插槽分发内容slot的用法
Mar 28 Javascript
微信小程序实现下拉框功能
Jul 16 Javascript
微信小程序使用车牌号输入法的示例代码
Aug 20 Javascript
javascript实现计算器功能详解流程
Nov 01 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 HandlerSocket的使用
2011/05/02 PHP
php的sprintf函数的用法 控制浮点数格式
2014/02/14 PHP
php中HTTP_REFERER函数用法实例
2014/11/21 PHP
PHP对文件进行加锁、解锁实例
2015/01/23 PHP
php中array_multisort对多维数组排序的方法
2020/06/21 PHP
Zend Framework教程之连接数据库并执行增删查的方法(附demo源码下载)
2016/03/21 PHP
PHP mysqli_free_result()与mysqli_fetch_array()函数详解
2016/09/21 PHP
PHP与服务器文件系统的简单交互
2016/10/21 PHP
laravel实现上传图片并在页面显示的例子
2019/10/14 PHP
jQuery 遍历json数组的实现代码
2020/09/22 Javascript
读jQuery之十三 添加事件和删除事件的核心方法
2011/08/23 Javascript
JavaScript可否多线程? 深入理解JavaScript定时机制
2012/05/23 Javascript
javascript 正则表达式相关应介绍
2012/11/27 Javascript
jquery text(),val(),html()方法区别总结
2013/11/04 Javascript
兼容主流浏览器的iframe自适应高度js脚本
2014/01/10 Javascript
使用Node.js为其他程序编写扩展的基本方法
2015/06/23 Javascript
使用Vue.js创建一个时间跟踪的单页应用
2016/11/28 Javascript
Node.js API详解之 assert模块用法实例分析
2020/05/26 Javascript
[00:15]TI9地铁玩家打卡
2019/08/11 DOTA
浅谈python内置变量-reversed(seq)
2017/06/21 Python
python下解压缩zip文件并删除文件的实例
2018/04/24 Python
python中csv文件的若干读写方法小结
2018/07/04 Python
Python通过TensorFlow卷积神经网络实现猫狗识别
2019/03/14 Python
python+openCV调用摄像头拍摄和处理图片的实现
2019/08/06 Python
python英语单词测试小程序代码实例
2019/09/09 Python
Django模板标签{% for %}循环,获取制定条数据实例
2020/05/14 Python
keras slice layer 层实现方式
2020/06/11 Python
Python绘图之二维图与三维图详解
2020/08/04 Python
html5实现多图片预览上传及点击可拖拽控件
2018/03/15 HTML / CSS
毕业生精彩的自我评价分享
2013/10/06 职场文书
大学生自荐书范文
2013/12/10 职场文书
新员工入职感言
2014/02/01 职场文书
关于奉献的演讲稿
2014/05/21 职场文书
亮剑观后感300字
2015/06/05 职场文书
公司处罚决定书
2015/06/24 职场文书
2016党员读书思廉心得体会
2016/01/23 职场文书