简单理解js的prototype属性及使用


Posted in Javascript onDecember 07, 2016

在进入正文之前,我得先说说我认识js的prototype这个东西的曲折过程。

百度js的prototype的文章,先看看,W3School关于prototype的介绍:

简单理解js的prototype属性及使用

你觉得这概念适合定义js的prototype这个东西吗?你是否也认为prototype是一个object对象的属性呢?是的话,请认真认真看我这篇文章,因为这篇文章会毁灭你的人生三观,呵呵,就是有这么严重,因为本人就是被这个定义给害惨的。

不得不说,看了网上的一些介绍prototype的文章,基本上都说prototype是对象的一个属性,于是,我也坚定的认为prototype是一个对象的属性,所以,我被了坑好久好久,由此,引发的后果就是,我一次次的误解别人写的含有prototype的js代码,也就是当别人亮出js的prototype这个属性来写js代码时,我看着他们写的代码都是 ····一头雾水·····

,悲催啊!所以,我恨死prototype这个东西了,因此,在这里,我今天必须把js的prototype属性道个明明白白。看官,请擦亮你的眼睛,仔细看我下面的实验。

当然,我希望诸位看官也能够静下心来,把我下面的实验重新做一遍,好证明我的结论是正确的。

同时,也为了证明·····我没有····骗你们·····,呵呵,废话不多说了,下面进入实验阶段。

先介绍一个下面要用到的函数,JSON.stringify(value)。

这个函数的作用是:把传入的参数value变成字符串,它有三个参数,第一个参数是必须的,其余的两个参数可填可不填。

关于JSON.stringify函数的作用请看这篇文章。https://3water.com/article/29893.htm,这里说的很清楚。

首先,测试W3Schol的定义到底行不行的通:

如果,真如W3Schol所说的那样,prototype是object的一个属性,那么,我们来创建一个对象,看看这个对象的prototype到底是啥。

var ob = { };//超级简单的空对象
alert(JSON.stringify(ob.prototype));

你觉得上面的代码会alert出什么呢?既然prototype是object的一个属性,那么上面肯定能够获取到什么东西对吧?但是,如果你拿这段代码去做实验了,你会被打脸的,因为它alert的东西是·········undefined··········,也就是说object这个属性prototype不是个东西,很残酷吧,但现实就是这样,任何对象引用prototype都会出现undefined,不信,你可以试一试。

我可以很明白的告诉你,prototype绝对不是给对象用的,对象根本没办法引用prototype这个属性,它真正的属主,其实是···········函数········,记住,能够引用prototype的东西绝对是函数,绝对是函数,绝对是函数,prototype是属于函数的一个属性,prototype是属于函数的一个属性,prototype是属于函数的一个属性,能够引用它的只有·····函数····,能够引用它的只有·····函数·····,能够引用它的只有····函数····,函数,函数,函数,重要的事情一定要说千百遍,呵呵,因为只有明确这一点,下面,你才明白我要讲的东西。别怪我这么墨迹啊!

下面,我要给prototype一个名副其实的定义:

prototype是函数的一个属性,是函数的原型对象。

就是这么简单,能看明白吗? prototype只能够被   函数     调用

别搞混了js的object对象和function函数,js的对象和函数绝对是两个概念,为什么?因为js的function函数可以new出object对象啊,是吧?这个你总该知道吧?

下面,来做试验证明我的结论。

 

//首先定义一个有名函数func
function func(){
  
}
alert(func.prototype);

你说,上面的代码会alert什么呢?还会不会是undefined的呢?我敢肯定的告诉你绝对不是undefined的,因为本人已经alert过了,呵呵。

上面,弹出的窗口是:

简单理解js的prototype属性及使用 

没错,返回的就是对象,这回你肯相信我,能够调用prototype的一定是函数了吧?object引用prototype的时候给你返回的是一个不是东西的东西undefined,函数引用prototype的时候给你返回一个真真实实存在的东西object的,这还不够证明prototype是给函数用的吗?还不能够证明对象是不能引用prototype的吗?呵呵,又多说了。

上面我已经说过,prototype是函数的一个属性,也是函数的原型对象,而这里func函数引用prototype的时候返回的是一个对象object的,那么,结合这两个概念,你能得出什么结论呢?我想通过这不难得出结论:

prototype是········函数的原型对象············,这能理解吗?不能理解,没有关系,我们再来做一个实验,终于要用到文章开始给你们介绍的一个函数JSON.stringify()了。

function func(){
  
}
alert(JSON.stringify(func.prototype));

还是引用上面的函数func,只不过这里返回的是JSON.stringify()函数的返回值。

简单理解js的prototype属性及使用

你没有看错,这里alert的结果是一个空对象,这证明,prototype的的确确属于函数的属性,并且函数的prototype属性的js数据类型是对象,明白不?为什么现在是一个空对象?你有没有想过?为什么呢?请思考这个问题三秒钟,假如想不出来,那么没有关系,下面,我来解释。

先看,实验代码:

function func(){
  
}
func.prototype.name ='prototype是函数的的属性,本质是函数的原型对象';
alert(JSON.stringify(func.prototype))

你说,上面的代码会alert出什么呢?请看下面:

简单理解js的prototype属性及使用

你没有看错,此刻,终于alert出东西来了,我在这里给prototype赋于一个属性name,所以,我这个时候在alert函数func的prototype时,你看到有值了吗?看到了prototype的属性name值了吗?现在再想想,为什么上面第一层alert函数func.prototype的时候,它是一个空对象呢?而现在它又是一个有值的对象呢?

原因很简单呢,因为第一次的时候,我没有给函数的属性func.prototype赋予name属性,也没有给name属性赋值啊,而现在我已经给函数的属性func.prototype赋予属性name,并且赋值为········prototype是函数的的属性,本质是函数的原型对象······,所以,现在alert函数的属性func.prototype的时候它就有值啦,对吧?

因此,这里得出结论:

prototype是函数的的属性,本质是函数的原型对象。

别以为js中只有对象才有属性,通过这里,我们也可以知道,其实js的函数也是有属性的,而且js的函数好像就只有这个属性prototype,而且js的这个函数属性同时还是函数的原型对象,你是不是被搞晕了?希望你没有被搞晕才好。

为什么说prototype是函数的一个属性呢?因为,只有函数才能调用prototype,而且是以这样的方式func.prototype调用的,这样的方式调用东西是不是和对象调用属性一模一样呢?是的,就是因为函数调用prototype的时候是和对象调用属性的时候一样的,我们才把prototype说成是函数的一个属性,而函数的这个属性其实是一个对象(这个是不是对象,上面已经证明了,这里就不再说明),所以说,这个prototype就是函数的属性,本质是函数的原型对象。

这里为什么强调说prototype的本质是函数的原型对象呢?

下面看代码证明,我的代码很简单的:

//定义一个函数
  function func(){
  
  }
  //给函数的属性prototype赋予一个方法get
  func.prototype.get=function(value){
    return value;//很简单,你给我什么我就输出什么
  }

你说,怎么调用上面那个get方法?

我给你一点提示,get是属于func函数的一个属性函数,既然是属性函数,那么我们怎么调用呢?

很简单,属性函数必须由它的对象来调用,那么我们怎么获取get的对象呢?很简单,用关键字new来实例化func函数的对象就行了吗?是吧?

下面,实例化func函数的一个对象ob1:

var ob1 = new func();
//用func实例化出来的对象来调用get属性函数
alert(ob1.get('hello,prototype原型对象'));

简单理解js的prototype属性及使用

没错,用func函数实例化出来的对象ob1,确实能够调用get函数,上面已经利用ob1调用get函数alert出来了,这就证明func函数的实例对象是拥有get这个属性函数的,对吧?这么明显,就不用说明了吧。

如果,你不信必须要用实例化func的对象来调用get函数,你可以试试直接用func调用get函数,也就是说,你可以尝试着func.get()调用一下get函数看看,看func它到底能不能够直接调用get函数。我想一定报错,呵呵,原因是什么,你自己想。

那么,说了这么多,我还是没有说明,为什么我说prototype的本质是函数的原型对象啊?对吧?

请看,下面的代码:

var ob2 = new func();
//用func实例化出来的对象来调用get属性方法
alert(ob2.get('我依然是func实例化出来的对象'));

简单理解js的prototype属性及使用

看到没有,我还是再次利用func函数实例化一个ob2,这个对象依然能够调用get属性函数,这说明什么了呢?这说明了,利用func对象实例化的所有对象都可以调用get这个属性函数。既然如此,你说,prototype这个属性如果不是函数func的原型对象的话,那么为什么给prototype赋予的属性函数get能够被func所有实例化的对象所调用呢?假如prototype的本质不是func函数的原型对象,那么依据func函数实例化出来的对象就不可能一个个都能够调用get这个属性方法,对吧?为什么?我们来个比例,你说,一个不是源头的东西,它能影响到所有的东西吗?不能够吧?因此,这里得出结论:

prototype是函数的一个属性,本质就是函数的原型对象。

整篇文章就是为了说明这个结论。无他。希望看官能看懂这篇文章。对于prototype的应用下篇文章再讲,在此打住。

特别指出:

  • Array.prototype是一个数组
  • String.prototype是一个字符串
  • Object.prototype是一个对象

这三个特殊例子,不像构造函数的prototype一样,当然,假如你真的理解prototype是函数的一个原型对象的话,你应该知道,数组的原型对象应该是一个数组,而不可能是一个对象吧?字符串的原型对象应该是字符串而不可能是对象吧?详情请看下一篇文章。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
单击浏览器右上角的X关闭窗口弹出提示的小例子
Jun 12 Javascript
jQuery中replaceAll()方法用法实例
Jan 16 Javascript
基于Jquery+div+css实现弹出登录窗口(代码超简单)
Oct 27 Javascript
jQuery 全选 全不选 事件绑定的实现代码
Jan 23 Javascript
微信小程序如何获知用户运行小程序的场景教程
May 17 Javascript
Angularjs的键盘事件的绑定
Jul 27 Javascript
基于js 本地存储(详解)
Aug 16 Javascript
去掉vue 中的代码规范检测两种方法(Eslint验证)
Mar 21 Javascript
vue中keep-alive的用法及问题描述
May 15 Javascript
Angular5中状态管理的实现
Sep 03 Javascript
什么时候不能在 Node.js 中使用 Lock Files
Jun 24 Javascript
vue element el-transfer增加拖拽功能
Jan 15 Vue.js
Bootstrap基本组件学习笔记之列表组(11)
Dec 07 #Javascript
Bootstrap基本样式学习笔记之图片(6)
Dec 07 #Javascript
JavaScript学习笔记--常用的互动方法
Dec 07 #Javascript
详解JavaScript的内置对象
Dec 07 #Javascript
Bootstrap基本样式学习笔记之标签(5)
Dec 07 #Javascript
Bootstrap基本样式学习笔记之按钮(4)
Dec 07 #Javascript
jQuery中get方法用法分析
Dec 07 #Javascript
You might like
php实现兼容2038年后Unix时间戳转换函数
2015/03/18 PHP
PHP中创建和验证哈希的简单方法实探
2015/07/06 PHP
php similar_text()函数的定义和用法
2016/05/12 PHP
PHP中Socket连接及读写数据超时问题分析
2016/07/19 PHP
CI框架附属类用法分析
2018/12/26 PHP
Dom 学习总结以及实例的使用介绍
2013/04/24 Javascript
jQuery数据缓存功能的实现思路及简单模拟
2013/05/27 Javascript
js获取IFRAME当前的URL的方法
2013/11/13 Javascript
利用JS进行图片的切换即特效展示图片
2013/12/03 Javascript
浏览器图片选择预览、旋转、批量上传的JS代码实现
2013/12/04 Javascript
完美解决IE低版本不支持call与apply的问题
2013/12/05 Javascript
JS获取随机数函数可自定义最小值最大值
2014/05/08 Javascript
使用focus方法让光标默认停留在INPUT框
2014/07/29 Javascript
AngularJs根据访问的页面动态加载Controller的解决方案
2015/02/04 Javascript
关于延迟加载JavaScript
2015/05/05 Javascript
ExtJS 4.2 Grid组件单元格合并的方法
2016/10/12 Javascript
Vue注册组件命名时不能用大写的原因浅析
2019/04/25 Javascript
express框架下使用session的方法
2019/07/31 Javascript
vue-video-player 解决微信自动全屏播放问题(横竖屏导致样式错乱问题)
2020/02/25 Javascript
vue将文件/图片批量打包下载zip的教程
2020/10/21 Javascript
python 队列详解及实例代码
2016/10/18 Python
python 动态加载的实现方法
2017/12/22 Python
Python+tkinter使用80行代码实现一个计算器实例
2018/01/16 Python
Python3 利用requests 库进行post携带账号密码请求数据的方法
2018/10/26 Python
python之列表推导式的用法
2019/11/29 Python
html5指南-3.如何实现html元素拖拽功能
2013/01/07 HTML / CSS
Kneipp克奈圃美国官网:德国百年精油配方的传承
2018/02/07 全球购物
Eagle Eyes Optics鹰眼光学:高性能太阳镜
2018/12/07 全球购物
医务人员竞聘职务自我评价分享
2013/11/08 职场文书
甜点店创业计划书
2014/01/27 职场文书
优秀教师获奖感言
2014/01/31 职场文书
大学生优秀班干部事迹材料
2014/05/26 职场文书
党员个人公开承诺书
2014/08/29 职场文书
先进集体事迹材料范文
2014/12/25 职场文书
2019年思想汇报
2019/06/20 职场文书
Redis IP地址的绑定的实现
2021/05/08 Redis