关于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 相关文章推荐
jquery操作checked属性以及disabled属性的多种方法
Jun 20 Javascript
纯javascript代码实现计算器功能(三种方法)
Sep 07 Javascript
基于jquery插件实现拖拽删除图片功能
Aug 27 Javascript
BootStrap智能表单实战系列(三)分块表单配置详解
Jun 13 Javascript
微信小程序五星评分效果实现代码
Apr 06 Javascript
详解Vue 普通对象数据更新与 file 对象数据更新
Apr 26 Javascript
详谈DOM简介及节点、属性、查找节点的方法
Nov 16 Javascript
分享ES6的7个实用技巧
Jan 18 Javascript
babel之配置文件.babelrc入门详解
Feb 22 Javascript
Vue项目报错:Uncaught SyntaxError: Unexpected token
Nov 10 Javascript
layer.alert回调函数执行关闭弹窗的实例
Sep 11 Javascript
vue常用高阶函数及综合实例
Feb 25 Vue.js
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 破解防盗链图片函数
2008/12/09 PHP
THINKPHP+JS实现缩放图片式截图的实现
2010/03/07 PHP
php实现简单的MVC框架实例
2015/09/23 PHP
Symfony实现行为和模板中取得request参数的方法
2016/03/17 PHP
Yii2.0实现生成二维码功能实例
2017/10/24 PHP
php打开本地exe程序,js打开本地exe应用程序,并传递相关参数方法
2018/02/06 PHP
PHP实现文件上传操作和封装
2020/03/04 PHP
来自国外的页面JavaScript文件优化
2010/12/08 Javascript
jquery 实现上下滚动效果示例代码
2013/08/09 Javascript
jquery插件开发之实现google+圈子选择功能
2014/03/10 Javascript
写出高效jquery代码的19条指南
2014/03/19 Javascript
Javascript this 关键字 详解
2014/10/22 Javascript
jquery实现图片随机排列的方法
2015/05/04 Javascript
JQuery中两个ul标签的li互相移动实现方法
2015/05/18 Javascript
使用Node.js实现ORM的一种思路详解(图文)
2017/10/24 Javascript
JavaScript框架Angular和React深度对比
2017/11/20 Javascript
nodejs初始化init的示例代码
2018/10/10 NodeJs
微信小程序分享功能onShareAppMessage(options)用法分析
2019/04/24 Javascript
Node绑定全局TraceID的实现方法
2019/11/14 Javascript
Node.js学习之内置模块fs用法示例
2020/01/22 Javascript
vue实现分页的三种效果
2020/06/23 Javascript
用JavaScript实现贪吃蛇游戏
2020/10/23 Javascript
详解Django框架中用context来解析模板的方法
2015/07/20 Python
详解Python实现多进程异步事件驱动引擎
2017/08/25 Python
Django ORM框架的定时任务如何使用详解
2017/10/19 Python
python链接oracle数据库以及数据库的增删改查实例
2018/01/30 Python
Python多线程中阻塞(join)与锁(Lock)使用误区解析
2018/04/27 Python
python求加权平均值的实例(附纯python写法)
2019/08/22 Python
Office DEPOT法国官网:欧迪办公用品采购
2018/01/03 全球购物
幼儿园义卖活动方案
2014/01/17 职场文书
旅游管理毕业生自荐书
2014/02/02 职场文书
经销商订货会主持词
2014/03/27 职场文书
政风行风整改报告
2014/11/06 职场文书
MySQL空间数据存储及函数
2021/09/25 MySQL
java多态注意项小结
2021/10/16 Java/Android
python高温预警数据获取实例
2022/07/23 Python