关于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 相关文章推荐
JS查看对象功能代码
Apr 25 Javascript
基于Jquery实现表格动态分页实现代码
Jun 21 Javascript
js实现点击按钮后给Div图层设置随机背景颜色的方法
May 06 Javascript
JS实现弹出浮动窗口(支持鼠标拖动和关闭)实例详解
Aug 06 Javascript
JS更改select内option属性的方法
Oct 14 Javascript
jquery自定义插件——window的实现【示例代码】
May 06 Javascript
微信小程序登录态控制深入分析
Apr 12 Javascript
常用的 JS 排序算法 整理版
Apr 05 Javascript
js动态引入的四种方法
May 05 Javascript
js+html5实现手机九宫格密码解锁功能
Jul 30 Javascript
在Koa.js中实现文件上传的接口功能
Oct 08 Javascript
Node.js API详解之 V8模块用法实例分析
Jun 05 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 组件化编程技巧
2009/06/06 PHP
Laravel框架中扩展函数、扩展自定义类的方法
2014/09/04 PHP
PHP数据分析引擎计算余弦相似度算法示例
2017/08/08 PHP
PHP 多任务秒级定时器的实现方法
2018/05/13 PHP
php处理多图上传压缩代码功能
2018/06/13 PHP
PHP的mysqli_select_db()函数讲解
2019/01/23 PHP
php字符串过滤strip_tags()函数用法实例分析
2019/06/24 PHP
jQuery中animate动画第二次点击事件没反应
2015/05/07 Javascript
详解js中Number()、parseInt()和parseFloat()的区别
2016/12/20 Javascript
vuejs绑定class和style样式
2017/04/11 Javascript
jquery图片放大镜效果
2017/06/23 jQuery
vue2.0设置proxyTable使用axios进行跨域请求的方法
2017/10/19 Javascript
动态加载权限管理模块中的Vue组件
2018/01/16 Javascript
node.js使用redis储存session的方法
2018/09/26 Javascript
vue权限管理系统的实现代码
2019/01/17 Javascript
js实现删除json中指定的元素
2020/09/22 Javascript
[45:16]完美世界DOTA2联赛PWL S3 Magma vs Phoenix 第一场 12.12
2020/12/16 DOTA
python实现的解析crontab配置文件代码
2014/06/30 Python
Python中的random()方法的使用介绍
2015/05/15 Python
Python OS模块常用函数说明
2015/05/23 Python
NLTK 3.2.4 环境搭建教程
2018/09/19 Python
python实践项目之监控当前联网状态详情
2019/05/23 Python
python函数的万能参数传参详解
2019/07/26 Python
Python实现GIF图倒放
2020/07/16 Python
python 实现全球IP归属地查询工具
2020/12/18 Python
深入解析HTML5的IndexedDB索引数据库
2015/09/14 HTML / CSS
芬兰攀岩、山地运动和户外活动用品购物网站:Bergfreunde
2016/10/06 全球购物
TUMI马来西亚官方网站:国际领先的高品质商旅箱包品牌
2018/04/26 全球购物
英国买鞋网站:Charles Clinkard
2019/11/14 全球购物
应届毕业生个人自荐信范文
2013/11/30 职场文书
初中生操行评语大全
2014/04/24 职场文书
书法兴趣小组活动总结
2014/07/07 职场文书
2015年医药代表工作总结
2015/04/25 职场文书
先进基层党组织主要事迹材料
2015/11/03 职场文书
python3 sqlite3限制条件查询的操作
2021/04/07 Python
MySQL数据管理操作示例讲解
2022/12/24 MySQL