关于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 相关文章推荐
prototype与jquery下Ajax实现的差别
Sep 13 Javascript
js 使用form表单select类实现级联菜单效果
Dec 19 Javascript
javascript的几种继承方法介绍
Mar 22 Javascript
使用jQuery处理AJAX请求的基础学习教程
May 10 Javascript
微信小程序 地图(map)实例详解
Nov 16 Javascript
JavaScript实现一个空中避难的小游戏
Jun 06 Javascript
网页爬虫之cookie自动获取及过期自动更新的实现方法
Mar 06 Javascript
微信小程序scroll-view仿拼多多横向滑动滚动条
Apr 21 Javascript
JavaScript引用类型RegExp基本用法详解
Aug 09 Javascript
使用webpack编译es6代码的方法步骤
Apr 28 Javascript
node.js中stream流中可读流和可写流的实现与使用方法实例分析
Feb 13 Javascript
JavaScript实现简单验证码
Aug 24 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
用Socket发送电子邮件
2006/10/09 PHP
PHP调用MySQL的存储过程的实现代码
2008/08/12 PHP
浅析php过滤html字符串,防止SQL注入的方法
2013/07/02 PHP
php实现约瑟夫问题的方法小结
2015/03/23 PHP
php微信高级接口群发 多客服
2016/06/23 PHP
深入分析PHP设计模式
2020/06/15 PHP
一段多浏览器的&quot;复制到剪贴板&quot;javascript代码
2007/03/27 Javascript
Javascript仿PHP $_GET获取URL中的参数
2014/05/12 Javascript
jQuery实现复选框成对选择及对应取消的方法
2015/03/03 Javascript
浅谈javascript实现八大排序
2015/04/27 Javascript
jQuery Mobile开发中日期插件Mobiscroll使用说明
2016/03/02 Javascript
JavaScript中的跨浏览器事件操作的基本方法整理
2016/05/20 Javascript
jQuery用FormData实现文件上传的方法
2016/11/21 Javascript
jQuery实现倒计时(倒计时年月日可自己输入)
2016/12/02 Javascript
vue.js实例todoList项目
2017/07/07 Javascript
解决vue页面DOM操作不生效的问题
2018/03/17 Javascript
微信小程序首页的分类功能和搜索功能的实现思路及代码详解
2018/09/11 Javascript
Vue中使用create-keyframe-animation与动画钩子完成复杂动画
2019/04/09 Javascript
手把手带你搭建一个node cli的方法示例
2020/08/07 Javascript
javascript canvas实现简易时钟例子
2020/09/05 Javascript
在Python中使用itertools模块中的组合函数的教程
2015/04/13 Python
python制作小说爬虫实录
2017/08/14 Python
python分治法求二维数组局部峰值方法
2018/04/03 Python
自学python的建议和周期预算
2019/01/30 Python
Python多线程同步---文件读写控制方法
2019/02/12 Python
pytorch 状态字典:state_dict使用详解
2020/01/17 Python
手把手教你进行Python虚拟环境配置教程
2020/02/03 Python
如何通过命令行进入python
2020/07/06 Python
英国马莎百货官网:Marks & Spencer
2016/07/29 全球购物
思想政治教育专业个人求职信范文
2013/12/20 职场文书
二年级班级文化建设方案
2014/05/10 职场文书
学生抄袭作业的检讨书
2014/10/02 职场文书
思想道德自我评价2015
2015/03/09 职场文书
校园广播稿范文
2015/08/19 职场文书
Springboot配置suffix指定mvc视图的后缀方法
2021/07/03 Java/Android
【海涛DOTA】D-cup邀请赛NV.cn vs DT.Love
2022/04/01 DOTA