位置: 编程技术 - 正文

跟我学习javascript的prototype,getPrototypeOf和__proto__(java教程)

编辑:rootadmin

推荐整理分享跟我学习javascript的prototype,getPrototypeOf和__proto__(java教程),希望有所帮助,仅作参考,欢迎阅读内容。

文章相关热门搜索词:java script教程,java script教程,java learning,java教程,java script怎么学,java script,java script怎么学,java script,内容如对您有帮助,希望把文章链接给更多的朋友!

一、深入理解prototype, getPrototypeOf和_ proto _

prototype,getPropertyOf和 _ proto _ 是三个用来访问prototype的方法。它们的命名方式很类似因此很容易带来困惑。

它们的使用方式如下:

C.prototype: 一般用来为一个类型建立它的原型继承对象。比如C.prototype = xxx,这样就会让使用new C()得到的对象的原型对象为xxx。当然使用obj.prototype也能够得到obj的原型对象。 getPropertyOf: Object.getPropertyOf(obj)是ES5中用来得到obj对象的原型对象的标准方法。 _ proto _: obj._ proto _是一个非标准的用来得到obj对象的原型对象的方法。

为了充分了解获取原型的各种方式,以下是一个例子:

User函数拥有一个默认的prototype属性,该属性的值是一个空对象。在以上的例子中,向prototype对象添加了两个方法,分别是toString和checkPassword。当调用User构造函数得到一个新的对象u时,它的原型对象会被自动赋值到User.prototype对象。即u.prototype === User.prototype会返回true。

User函数,User.prototype,对象u之间的关系可以表示如下:

上图中的箭头表示的是继承关系。当访问u对象的某些属性时,会首先尝试读取u对象上的属性,如果u对象上并没有这个属性,就会查找其原型对象。

比如当调用u.checkPassword()时,因为checkPassword定义在其原型对象上,所以在u对象上找不到该属性,就在u的原型上查找,查找顺序是u-> u.prototype(User.prototype)。

前面提到过,getPrototypeOf方法是ES5中用来得到某个对象的原型对象的标准方法。因此:

在一些环境中,同时提供了一个非标准的_ proto _ 属性用来得到某个对象的原型对象。当环境不提供ES5的标准方法getPrototypeOf方法时,可以暂时使用该属性作为替代。可以使用下面的代码测试环境中是否支持_ proto _:

所以在JavaScript中,类的概念是由构造函数(User)和用于实例间共享方法的原型对象(User.prototype)共同完成的。构造函数中负责构造每个对象特有的属性,比如上述例子中的name和password属性。而其原型对象中负责存放所有对象共有的属性,比如上述例子中的checkPassword和toString方法。就像下面这张图表示的那样:

二、获取对象优先使用Object.getPrototypeOf,而不是_ proto _

在ES5中引入了Object.getPrototypeOf作为获取对象原型对象的标准API。但是在很多执行环境中,也提供了一个特殊的_ proto _属性来达到同样的目的。

因为并不是所有的环境都提供了这个_ proto _属性,且每个环境的实现方式各不相同,因此一些结果可能不一致,例如,对于拥有null原型的对象:

跟我学习javascript的prototype,getPrototypeOf和__proto__(java教程)

所以当环境中支持Object.getPrototypeOf方法时,优先使用它。即使不支持,也可以为了实现一个:

上述代码首先会对当前环境进行检查,如果已经支持了Object.getPrototypeOf,就不会再重复定义。

三、绝不要修改_ proto _

和Object.getPrototypeOf相比,_ proto _的特殊之处还体现在它能够修改一个对象的原型继承链。因为它是一个属性,除了执行获取它的操作外,还能够对它进行设置。

但是,绝不要修改_ proto _。原因如下:

首先,最显而易见的原因就是便携性。因为不是所有的JavaScript执行环境都支持这一属性,所以使用了_ proto _ 之后,代码就不能在那些不支持_ proto _的环境中运行了。 其次,是性能上的考虑。现在的JavaScript引擎的实现都会针对对象属性的存取作出大量的优化,因为这些操作是最常用的。当修改了对象的_ proto _后,就相当于修改了对象的整个继承结构,这样做回导致很多优化都不再可用。 最后,最重要的原因是需要保证程序的可靠性。因为改变_ proto _属性后,对象的原型继承链也许会被完全地改变。当程序中有其他代码依赖于原来的继承链时,就会出现不可意料的错误。通常而言,原型继承链需要保持稳定。

当需要为一个新创建的对象赋予一个原型对象时,可以使用ES5提供的Object.create方法。对于未实现ES5标准的环境,可以给出来一个不依赖于_ proto _的Object.create方法的实现。

四、解决 _ proto _兼容问题, 让构造函数不再依赖new关键字

在将function当做构造函数使用时,需要确保该函数是通过new关键字进行调用的。

如果在调用上述构造函数时,忘记了使用new关键字,那么:

可以发现得到的u是undefined,而this.name以及this.passwordHash则被赋了值。但是这里的this指向的则是全局对象。

如果将构造函数声明为依赖于strict模式:

那么在忘记使用new关键字的时候,在调用this.name= name的时候会抛出TypeError错误。这是因为在strict模式下,this的默认指向会被设置为undefined而不是全局对象。

那么,是否有种方法能够保证在调用一个函数时,无论使用了new关键字与否,该函数都能够被当做构造函数呢?下面的代码是一种实现方式,使用了instanceof操作:

以上的if代码块就是用来处理没有使用new进行调用的情况的。当没有使用new时,this的指向并不是一个User的实例,而在使用了new关键字时,this的指向是一个User类型的实例。

另一个更加适合在ES5环境中使用的实现方式如下:

Object.create方法是ES5提供的方法,它能够接受一个对象作为新创建对象的prototype。那么在非ES5环境中,就需要首先实现一个Object.create方法:

实际上,Object.create方法还有接受第二个参数的版本,第二个参数表示的是在新创建对象上赋予的一系列属性。

当上述的函数确实使用了new进行调用时,也能够正确地得到返回的新建对象。这得益于构造器覆盖模式(Constructor Override Pattern)。该模式的含义是:使用了new关键字的表达式的返回值能够被一个显式的return覆盖。正如以上代码中使用了return self来显式定义了返回值。

当然,以上的工作在某些情况下也不是必要的。但是,当一个函数是需要被当做构造函数进行调用时,必须对它进行说明,使用文档是一种方式,将函数的命名使用首字母大写的方式也是一种方式(基于JavaScript语言的一些约定俗成)。

标签: java教程

本文链接地址:https://www.jiuchutong.com/biancheng/384629.html 转载请保留说明!

上一篇:JavaScript代码实现禁止右键、禁选择、禁粘贴、禁shift、禁ctrl、禁alt(javascript 代码)

下一篇:js弹出对话框方式小结(js中弹出对话框)

  • 发票上的不含税单价怎么算的
  • 企业季度报什么税
  • 简易计税项目税金要计入成本吗
  • 销售开红字的账务处理
  • 金税三期报税软件
  • 融资租赁承租方会计账务处理流程
  • 计提的费用年底要冲回吗
  • 员工工伤保险报销走什么科目
  • 小规模季度不超过多少不用交税
  • 培训费用可以开专票吗
  • 办税人员需要会计证吗
  • 涉农和中小企业贷款分类证明没有就不能进行税前扣除么
  • 文化事业建设费计入什么科目
  • 贷款买电脑的故事
  • 制造费用分摊的账务处理怎么做?
  • 地下车库是否需要设置消防电梯?
  • 50万股份分红
  • 小规模给个人开普票怎么填写
  • 电子发票上传平台失败是什么意思
  • 帮别的公司代销产品,对方公司不开具发票怎么做帐
  • 公司账户替别人过账
  • win11专业版企业版家庭版哪个玩游戏好
  • 复核内容有哪些?
  • 在建工程的施工方案可以外传吗
  • 电脑管家免费wifi
  • 酒店没有营业执照开业员工有责任吗
  • 企业的工资薪金等现金支出只能通过什么办理
  • 发票是否可以作为收款依据
  • 处置二手固定资产
  • 达拉斯位置
  • 应收账款的定义和特点
  • html中a标签怎么引用图片
  • AIGC之GPT-4:GPT-4的简介(核心原理/意义/亮点/技术点/缺点/使用建议)、使用方法、案例应用(计算能力/代码能力/看图能力等)之详细攻略
  • 股东分红放到哪个会计科目
  • 弥补以前年度亏损报表怎么填
  • 关税完税价格计算增值税
  • vue this.$el
  • js在数组中查找指定元素
  • 旅行社差额征税税率5%
  • 累计折旧如何计算使用年限
  • mysql运行报错
  • 可供出售金融资产新准则叫什么
  • 固定资产评估减值还是升值
  • 扣员工工作服费用合法吗?
  • 如何确认产品销售收入
  • 企业发生的开办费用计入营业外支出账户
  • 银行利息为什么用红字
  • 免息分期付款怎么办理
  • 报表主营业务收入计算公式
  • 审车费用表
  • 报价中含税和不含税比例
  • mysql的用户管理与权限管理
  • sql server怎么向表里添加数据
  • Windows Server 2008脱机文件配置攻略
  • 详述社会体育学科的研究对象
  • 隐藏的系统
  • win7删除windows.old
  • ubuntu中用root删除文件夹
  • linux find 查找文件并重命名
  • linux获取操作命令的使用方法或参数选项内容
  • w10怎么创建此电脑
  • 控制面板win8在哪里
  • android滑动选择
  • tomcat怎么启动
  • socket pf_inet
  • easyui-accordion
  • js必须掌握的知识点
  • JavaScript事件处理器中的event参数使用介绍
  • linux监控网络请求
  • python视频下载
  • shell脚本实例精讲
  • unity制作的2d游戏
  • 菜鸟教程jstl
  • jquery如何做登录
  • android如何防止js注入
  • jQuery通过ajax请求php遍历json数组到table中的代码(推荐)
  • 税务系统 网络发票
  • 出口企业能否更换法人
  • 纳税信用评级b是多少分
  • 公积金提取需要几个工作日
  • 免责声明:网站部分图片文字素材来源于网络,如有侵权,请及时告知,我们会第一时间删除,谢谢! 邮箱:opceo@qq.com

    鄂ICP备2023003026号

    网站地图: 企业信息 工商信息 财税知识 网络常识 编程技术

    友情链接: 武汉网站建设