关于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 设计模式 推荐
Oct 28 Javascript
javascript手工制作悬浮菜单
Feb 12 Javascript
个人总结的一些JavaScript技巧、实用函数、简洁方法、编程细节
Jun 10 Javascript
在Node.js应用中读写Redis数据库的简单方法
Jun 30 Javascript
javascript解决IE6下hover问题的方法
Jul 28 Javascript
微信小程序 获取设备信息 API实例详解
Oct 02 Javascript
js学习总结之DOM2兼容处理顺序问题的解决方法
Jul 27 Javascript
详解JS模块导入导出
Dec 20 Javascript
简述JS控制台的使用
Jul 15 Javascript
微信小程序开发之map地图组件定位并手动修改位置偏差
Aug 17 Javascript
vue实现图片懒加载的方法分析
Feb 05 Javascript
工作中常用js功能汇总
Nov 07 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
与空气斗智斗勇的经典《Overlord》,传说中的“无稽之谈”
2020/04/09 日漫
超级好用的一个php上传图片类(随机名,缩略图,加水印)
2010/06/30 PHP
关于session在PHP5的配置文件中的详细设置参数说明
2011/04/20 PHP
php urlencode()与urldecode()函数字符编码原理详解
2011/12/06 PHP
PHP 实现explort() 功能的详解
2013/06/20 PHP
PHP实现bitmap位图排序与求交集的方法
2016/07/28 PHP
js 创建快捷方式的代码(fso)
2010/11/19 Javascript
jQuery下通过$.browser来判断浏览器.
2011/04/05 Javascript
JQuery通过Ajax提交表单并返回结果
2011/07/31 Javascript
suggestion开发小结以及对键盘事件的总结(针对中文输入法状态)
2011/12/20 Javascript
js 加密压缩出现bug解决方案
2014/11/25 Javascript
JavaScript把数组作为堆栈使用的方法
2015/03/20 Javascript
jquery实现的树形目录实例
2015/06/26 Javascript
聊一聊JS中this的指向问题
2016/06/17 Javascript
浅谈js多维数组和hash数组定义和使用
2016/07/27 Javascript
Vue.js基础指令实例讲解(各种数据绑定、表单渲染大总结)
2017/07/03 Javascript
koa上传excel文件并解析的实现方法
2018/08/09 Javascript
bootstrap下拉框动态赋值方法
2018/08/10 Javascript
详解webpack2异步加载套路
2018/09/14 Javascript
微信小程序实现带缩略图轮播效果
2018/11/04 Javascript
jQuery实现高级检索功能
2019/05/28 jQuery
Vue.use()在new Vue() 之前使用的原因浅析
2019/08/26 Javascript
在vue中实现禁止屏幕滚动,禁止屏幕滑动
2020/07/22 Javascript
python调用新浪微博API项目实践
2014/07/28 Python
分析在Python中何种情况下需要使用断言
2015/04/01 Python
Python 数据结构之旋转链表
2017/02/25 Python
基于python3 类的属性、方法、封装、继承实例讲解
2017/09/19 Python
对Python中画图时候的线类型详解
2019/07/07 Python
Python如何将装饰器定义为类
2020/07/30 Python
celery在python爬虫中定时操作实例讲解
2020/11/27 Python
CSS实现定位元素居中的方法
2015/06/23 HTML / CSS
7 For All Mankind官网:美国加州洛杉矶的高级牛仔服装品牌
2018/12/20 全球购物
转让协议书范本
2014/04/15 职场文书
中国文明网向国旗敬礼活动精彩寄语2014
2014/09/27 职场文书
Python3 多线程(连接池)操作MySQL插入数据
2021/06/09 Python
centos8安装nginx1.9.1的详细过程
2021/08/02 Servers