关于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 相关文章推荐
在视频前插入广告
Nov 20 Javascript
一个不错的应用,用于提交获取文章内容,不推荐用
Mar 03 Javascript
Javascript 日期处理之时区问题
Oct 08 Javascript
实现点击列表弹出列表索引的两种方式
Mar 08 Javascript
二叉树先序遍历的非递归算法具体实现
Jan 09 Javascript
jQuery响应鼠标事件并隐藏与显示input默认值
Aug 24 Javascript
使用jQuery实现input数值增量和减量的方法
Jan 24 Javascript
jQuery+AJAX实现遮罩层登录验证界面(附源码)
Sep 13 Javascript
有关suggest快速删除后仍然出现下拉列表的bug问题
Dec 02 Javascript
Node.js连接MongoDB数据库产生的问题
Feb 08 Javascript
简单实现JS上传图片预览功能
Apr 14 Javascript
Vuex modules模式下mapState/mapMutations的操作实例
Oct 17 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 检查扩展库或函数是否可用的代码
2010/04/06 PHP
php绘图中显示不出图片的原因及解决
2014/03/05 PHP
ThinkPHP控制器间实现相互调用的方法
2014/10/31 PHP
PHP使用SWOOLE扩展实现定时同步 MySQL 数据
2017/04/09 PHP
IE和Firefox下javascript的兼容写法小结
2008/12/10 Javascript
写出高效jquery代码的19条指南
2014/03/19 Javascript
在Ubuntu上安装最新版本的Node.js
2014/07/14 Javascript
JavaScript中使用typeof运算符需要注意的几个坑
2014/11/08 Javascript
纯JS代码实现隔行变色鼠标移入高亮
2016/11/23 Javascript
JS实现动态添加DOM节点和事件的方法示例
2017/04/28 Javascript
Angularjs验证用户输入的字符串是否为日期时间
2017/06/01 Javascript
JavaScript实现多重继承的方法分析
2018/01/09 Javascript
vue项目tween方法实现返回顶部的示例代码
2018/03/02 Javascript
react高阶组件添加和删除props
2019/04/26 Javascript
如何进行微信公众号开发的本地调试的方法
2019/06/16 Javascript
微信小程序之几种常见的弹框提示信息实现详解
2019/07/11 Javascript
JavaScript 格式化数字、金额、千分位、保留几位小数、舍入舍去
2019/07/23 Javascript
jquery树形插件zTree高级使用详解
2019/08/16 jQuery
vue Treeselect 树形下拉框:获取选中节点的ids和lables操作
2020/08/15 Javascript
基于Python对象引用、可变性和垃圾回收详解
2017/08/21 Python
将python图片转为二进制文本的实例
2019/01/24 Python
python+selenium实现自动化百度搜索关键词
2019/06/03 Python
Python模块future用法原理详解
2020/01/20 Python
Python如何避免文件同名产生覆盖
2020/06/09 Python
解决python3.x安装numpy成功但import出错的问题
2020/11/17 Python
用CSS3实现无限循环的无缝滚动的实例代码
2017/07/04 HTML / CSS
Spartoo芬兰:欧洲最大的网上鞋店
2016/08/28 全球购物
简述网络文件系统NFS,并说明其作用
2016/10/19 面试题
自荐信的五个重要部分
2013/10/29 职场文书
环保小标语
2014/06/13 职场文书
英语教师个人工作总结
2015/02/09 职场文书
如何写好开幕词?
2019/06/24 职场文书
工作汇报材料难写?方法都在这里了!
2019/07/01 职场文书
爱心捐款倡议书:点燃希望,传递温暖
2019/11/04 职场文书
vue @click.native 绑定原生点击事件
2022/04/22 Vue.js
Python通用验证码识别OCR库ddddocr的安装使用教程
2022/07/07 Python