关于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 写类方式之六
Jul 05 Javascript
javascript 获取select下拉列表值的代码
Sep 07 Javascript
通过隐藏iframe实现文件下载的js方法介绍
Feb 26 Javascript
jQuery动画效果图片轮播特效
Jan 12 Javascript
BootStrap Progressbar 实现大文件上传的进度条的实例代码
Jun 27 Javascript
JavaScript算法教程之sku(库存量单位)详解
Jun 29 Javascript
promise处理多个相互依赖的异步请求(实例讲解)
Aug 03 Javascript
Angular4实现图片上传预览路径不安全的问题解决
Dec 25 Javascript
关闭Vue计算属性自带的缓存功能方法
Mar 02 Javascript
浅谈ng-zorro使用心得
Dec 03 Javascript
微信小程序云开发之使用云存储
May 17 Javascript
如何利用JS将手机号中间四位变成*号
Sep 29 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
星际争霸 Starcraft 发展史
2020/03/14 星际争霸
杏林同学录(三)
2006/10/09 PHP
将OICQ数据转成MYSQL数据
2006/10/09 PHP
php XPath对XML文件查找及修改实现代码
2011/07/27 PHP
PHP中error_reporting()用法详解
2015/08/31 PHP
dojo 之基础篇
2007/03/24 Javascript
用js实现的模拟jquery的animate自定义动画(2.5K)
2010/07/20 Javascript
JS分页效果示例
2013/10/11 Javascript
关于安卓手机微信浏览器中使用XMLHttpRequest 2上传图片显示字节数为0的解决办法
2016/05/17 Javascript
AngularJS实现用户登录状态判断的方法(Model添加拦截过滤器,路由增加限制)
2016/12/12 Javascript
原生js实现瀑布流布局
2017/03/08 Javascript
jQuery导航条固定定位效果实例代码
2017/05/26 jQuery
JavaScript之面向对象_动力节点Java学院整理
2017/06/29 Javascript
js实现把时间戳转换为yyyy-MM-dd hh:mm 格式(es6语法)
2017/12/28 Javascript
jQuery实现鼠标点击处心形漂浮的炫酷效果示例
2018/04/12 jQuery
JavaScript偏函数与柯里化实例详解
2019/03/27 Javascript
JS highcharts动态柱状图原理及实现
2020/10/16 Javascript
[15:28]DOTA2 HEROS教学视频教你分分钟做大人-剧毒术士
2014/06/13 DOTA
[01:00:35]2018DOTA2亚洲邀请赛3月30日B组 EffcetVSMineski
2018/03/31 DOTA
win10下Python3.6安装、配置以及pip安装包教程
2017/10/01 Python
pytorch使用指定GPU训练的实例
2019/08/19 Python
利用python汇总统计多张Excel
2020/09/22 Python
利用CSS的Sass预处理器(框架)来制作居中效果
2016/03/10 HTML / CSS
HTML5仿手机微信聊天界面
2016/03/18 HTML / CSS
巧克力领导品牌瑞士莲美国官网:Lindt Chocolate美国
2016/08/25 全球购物
美体小铺瑞典官方网站:The Body Shop瑞典
2018/01/27 全球购物
泰国折扣酒店预订:Hotels2Thailand
2018/03/20 全球购物
工商学院毕业生自荐信
2013/11/12 职场文书
毕业生的自我评价分享
2013/12/18 职场文书
关于人生的感言
2014/01/17 职场文书
网上开店必备创业计划书
2014/01/26 职场文书
英语国培研修感言
2014/02/13 职场文书
2014年小学重阳节活动策划方案
2014/09/16 职场文书
Spring Cloud Netflix 套件中的负载均衡组件 Ribbon
2022/04/13 Java/Android
微信小程序APP的事件绑定以及传递参数时的冒泡和捕获
2022/04/19 Javascript
springboot创建的web项目整合Quartz框架的项目实践
2022/06/21 Java/Android