关于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获取浏览器类型和版本的方法(js获取浏览器版本)
Mar 13 Javascript
js中string转int把String类型转化成int类型
Aug 13 Javascript
javascript通过元素id和name直接取得元素的方法
Apr 28 Javascript
JS实现随页面滚动显示/隐藏窗口固定位置元素
Feb 26 Javascript
深入浅析JavaScript的API设计原则
Jun 14 Javascript
深入理解jQuery layui分页控件的使用
Aug 17 Javascript
浅谈jquery采用attr修改form表单enctype不起作用的问题
Nov 25 Javascript
jQuery树控件zTree使用方法详解(一)
Feb 28 Javascript
简单的Vue异步组件实例Demo
Dec 27 Javascript
详解vue表单——小白速看
Apr 08 Javascript
Vue不能观察到数组length的变化
Jun 08 Javascript
解决vue数组中对象属性变化页面不渲染问题
Aug 09 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 CURL模拟登录新浪微博抓取页面内容 基于EaglePHP框架开发
2012/01/16 PHP
Yii框架页面渲染操作实例详解
2019/07/19 PHP
让人印象深刻的10个jQuery手风琴效果应用
2012/05/08 Javascript
jquery不会自动回收xmlHttpRequest对象 导致了内存溢出
2012/06/18 Javascript
页面回到顶部的三种实现(锚标记,js)
2012/10/01 Javascript
JavaScript对象和字串之间的转换实例探讨
2013/04/21 Javascript
JQuery+Ajax无刷新分页的实例代码
2014/02/08 Javascript
javascript实现当前页导航激活的方法
2015/02/27 Javascript
js实现的全国省市二级联动下拉选择菜单完整实例
2015/08/17 Javascript
浅析jQuery移动开发中内联按钮和分组按钮的编写
2015/12/04 Javascript
一个仿微博登陆邮箱提示框js开发案例
2016/07/28 Javascript
AngularJS基础 ng-value 指令简单示例
2016/08/03 Javascript
浅谈js中StringBuffer类的实现方法及使用
2016/09/02 Javascript
详细总结Javascript中的焦点管理
2016/09/17 Javascript
vue-router动态设置页面title的实例讲解
2018/08/30 Javascript
Vue cli3 库模式搭建组件库并发布到 npm的流程
2018/10/12 Javascript
Angular Material Icon使用详解
2018/11/07 Javascript
swiper.js插件实现pc端文本上下滑动功能示例
2018/12/03 Javascript
浅谈vuex的基本用法和mapaction传值问题
2019/11/08 Javascript
浅谈Vue组件单元测试究竟测试什么
2020/02/05 Javascript
Vue项目结合Vue-layer实现弹框式编辑功能(实例代码)
2020/03/11 Javascript
分享8个JavaScript库可更好地处理本地存储
2020/10/12 Javascript
[01:51]2014DOTA2西雅图邀请赛 MVP 外卡赛black场间采访
2014/07/09 DOTA
[56:45]DOTA2上海特级锦标赛D组小组赛#1 EG VS COL第一局
2016/02/28 DOTA
[48:11]完美世界DOTA2联赛 Magma vs GXR 第二场 11.07
2020/11/10 DOTA
详解Python命令行解析工具Argparse
2016/04/20 Python
Python实现图片滑动式验证识别方法
2017/11/09 Python
浅谈flask截获所有访问及before/after_request修饰器
2018/01/18 Python
使用python编写监听端
2018/04/12 Python
解决使用export_graphviz可视化树报错的问题
2019/08/09 Python
python怎么删除缓存文件
2020/07/19 Python
保护环境建议书
2014/03/12 职场文书
小学生清明节演讲稿
2014/09/05 职场文书
简单的个人租房协议书范本
2014/11/26 职场文书
零基础学java之循环语句的使用
2022/04/10 Java/Android
PostgreSQL数据库创建并使用视图以及子查询
2022/04/11 PostgreSQL