简单理解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 相关文章推荐
关于全局变量和局部变量的那些事
Jan 11 Javascript
JS和JQUERY获取页面大小,滚动条位置,元素位置(示例代码)
Dec 14 Javascript
JS父页面与子页面相互传值方法
Mar 05 Javascript
JavaScript处理解析JSON数据过程详解
Sep 11 Javascript
基于Bootstrap重置输入框内容按钮插件
May 12 Javascript
实例解析jQuery中proxy()函数的用法
May 24 Javascript
微信小程序开发之toast提示插件使用示例
Jun 08 Javascript
vue 2.0项目中如何引入element-ui详解
Sep 06 Javascript
MUI 实现侧滑菜单及其主体部分上下滑动的方法
Jan 25 Javascript
vue.js根据代码运行环境选择baseurl的方法
Feb 28 Javascript
解决包含在label标签下的checkbox在ie8及以下版本点击事件无效果兼容的问题
Oct 27 Javascript
Vue项目中Api的组织和返回数据处理的操作
Nov 04 Javascript
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
WINDOWS服务器安装多套PHP的另类解决方案
2006/10/09 PHP
PHP写的求多项式导数的函数代码
2012/07/04 PHP
header跳转和include包含问题详解
2012/09/08 PHP
php绘图中显示不出图片的原因及解决
2014/03/05 PHP
给WordPress的编辑后台添加提示框的代码实例分享
2015/12/25 PHP
PHP中使用jQuery+Ajax实现分页查询多功能操作(示例讲解)
2017/09/17 PHP
PHP实现Redis单据锁以及防止并发重复写入
2018/04/10 PHP
PHP数组array类常见操作示例
2020/05/15 PHP
JavaScript面向对象编程
2008/03/02 Javascript
js getElementsByTagName的简写方式
2010/06/27 Javascript
javascript中RegExp保留小数点后几位数的方法分享
2013/08/13 Javascript
js 数值转换为3位逗号分隔的示例代码
2014/02/19 Javascript
JQuery中模拟image的ajaxPrefilter与ajaxTransport处理
2015/06/19 Javascript
jquery实现简单文字提示效果
2015/12/02 Javascript
jQuery EasyUI之DataGrid使用实例详解
2016/01/04 Javascript
基于JS实现数字+字母+中文的混合排序方法
2016/06/06 Javascript
jquery动态创建div与input的实例代码
2016/10/12 Javascript
解决vue动态为数据添加新属性遇到的问题
2018/09/18 Javascript
Vue 指令实现按钮级别权限管理功能
2019/04/23 Javascript
bootstrapValidator表单校验、更改状态、新增、移除校验字段的实例代码
2020/05/19 Javascript
python处理html转义字符的方法详解
2016/07/01 Python
Python探索之ModelForm代码详解
2017/10/26 Python
创建pycharm的自定义python模板方法
2018/05/23 Python
Python实现的爬取网易动态评论操作示例
2018/06/06 Python
django框架面向对象ORM模型继承用法实例分析
2019/07/29 Python
解决Django中调用keras的模型出现的问题
2019/08/07 Python
详解Python3 中的字符串格式化语法
2020/01/15 Python
解决python和pycharm安装gmpy2 出现ERROR的问题
2020/08/28 Python
html5 canvas 简单画板实现代码
2012/01/05 HTML / CSS
通过HTML5规范搞定i、em、b、strong元素的区别
2017/03/04 HTML / CSS
VLAN和VPN有什么区别?分别实现在OSI的第几层?
2014/12/23 面试题
护士的自我鉴定
2014/02/07 职场文书
2015年食堂工作总结报告
2015/04/23 职场文书
实习证明格式范文
2015/06/16 职场文书
python实现三次密码验证的示例
2021/04/29 Python
聊聊CSS粘性定位sticky案例解析
2022/06/01 HTML / CSS