关于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 相关文章推荐
定时器(setTimeout/setInterval)调用带参函数失效解决方法
Mar 26 Javascript
浅析jquery ajax异步调用方法中不能给全局变量赋值的原因及解决方法
Jan 10 Javascript
浅谈JavaScript实现面向对象中的类
Dec 09 Javascript
基于JS实现移动端访问PC端页面时跳转到对应的移动端网页
Dec 24 Javascript
基于JS实现EOS隐藏错误提示层代码
Apr 25 Javascript
全面理解闭包机制
Jul 11 Javascript
使用JavaScript判断用户输入的是否为正整数(两种方法)
Feb 05 Javascript
js实现京东轮播图效果
Jun 30 Javascript
利用jQuery+localStorage实现一个简易的计时器示例代码
Dec 25 jQuery
JavaScript 判断iPhone X Series机型的方法
Jan 28 Javascript
JSONObject与JSONArray使用方法解析
Sep 28 Javascript
解决antd datepicker 获取时间默认少8个小时的问题
Oct 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
探讨php define()函数及defined()函数使用详解
2013/06/09 PHP
php简单计算年龄的方法(周岁与虚岁)
2016/12/06 PHP
比较详细的关于javascript中void(0)的具体含义解释
2007/08/02 Javascript
国外的为初学者写的JavaScript教程
2008/06/09 Javascript
关于IE7 IE8弹出窗口顶上
2008/12/22 Javascript
XmlUtils JS操作XML工具类
2009/10/01 Javascript
jQuery方法简洁实现隔行换色及toggleClass的使用
2013/03/15 Javascript
初识Node.js
2015/03/20 Javascript
javaScript中with函数用法实例分析
2015/06/08 Javascript
测试IE浏览器对JavaScript的AngularJS的兼容性
2015/06/19 Javascript
JavaScript处理解析JSON数据过程详解
2015/09/11 Javascript
JS获取一个未知DIV高度的方法
2016/08/09 Javascript
JS获取当前使用的浏览器名字以及版本号实现方法
2016/08/19 Javascript
微信小程序-消息提示框实例
2016/11/24 Javascript
Bootstrap基本插件学习笔记之Popover提示框(19)
2016/12/08 Javascript
Vue中的vue-resource示例详解
2018/11/02 Javascript
JS实现简单随机3D骰子
2019/10/24 Javascript
jQuery表单校验插件validator使用方法详解
2020/02/18 jQuery
[40:03]DOTA2上海特级锦标赛主赛事日 - 1 败者组第一轮#1EHOME VS Archon
2016/03/02 DOTA
[03:42]2016国际邀请赛中国区预选赛首日现场玩家采访
2016/06/26 DOTA
Python的Flask框架中Flask-Admin库的简单入门指引
2015/04/07 Python
python实现的简单抽奖系统实例
2015/05/22 Python
Empty test suite.(PyCharm程序运行错误的解决方法)
2018/11/30 Python
python3通过selenium爬虫获取到dj商品的实例代码
2019/04/25 Python
pandas读取CSV文件时查看修改各列的数据类型格式
2019/07/07 Python
python实现逆滤波与维纳滤波示例
2020/02/26 Python
python 如何快速复制序列
2020/09/07 Python
详解css3中 text-fill-color属性
2019/07/08 HTML / CSS
移动端适配 使px自动转换rem
2019/08/26 HTML / CSS
HTML5之SVG 2D入门5—颜色的表示及定义方式
2013/01/30 HTML / CSS
HTML5图片层叠的实现示例
2020/07/07 HTML / CSS
美国最大的香水出口:FragranceX.com
2017/11/04 全球购物
会计与审计专业大专生求职信
2013/10/03 职场文书
计算机专业优秀大学生自我总结
2014/01/21 职场文书
身边的榜样活动方案
2014/08/20 职场文书
会计稽核岗位职责
2015/04/13 职场文书