热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

ES6中一些新特性的底层实现

最近在看ES6的入门教程,分类很细,知识点也很多,然后脑壳一抽,觉得是不是应该做点什么呢?哈哈,然后就更了此文,若有不当,欢迎指正!此文会不定时更新,毕竟是边看边总结,随时会有补充哒!

最近在看ES6的入门教程,分类很细,知识点也很多,然后脑壳一抽,觉得是不是应该做点什么呢?哈哈,然后就更了此文,若有不当,欢迎指正!

此文会不定时更新,毕竟是边看边总结,随时会有补充哒!

1.Object.freeze():冻结对象

首先,为什么要冻结对象呢?

在ES6中有一种变量声明方法为const,当我们使用这个命令来声明一个变量的时候,其实本意是想声明一个只读的常量,也就是说,我们并不希望在以后改变它。然而,但是,想象总是美好滴,对于复合型变量(数组,对象),变量名指向的并不是数据本身,而是数据所在的地址。这就意味着我们用const声明了一个对象,却依然能够向其添加或删除或修改属性很显然,这样的做法在一定程度上违背了我们设计这个变量的初衷了。所以,我们需要冻结一个对象,使得对其属性的增删操作无法生效,这就是Object.freeze()的作用啦!

然后呢,为了彻底冻结一个对象,单靠Object.freeze()肯定是不行的啦,我们不仅要将对象本身冻结,还要将对象的属性也冻结,这个对象属性尤指typeof类型为object的属性。

下面,贴代码:

var cOnstantize=(obj) => {
	Object.freeze(obj);
	Object.keys(obj).forEach((key,value) => {
		if(typeof obj[key]==="object"){
			constantize(obj[key]);
		}
	});
};

2.Object.is():比较两个值是否严格相等

首先,我们需要知道,ES6中每一个新出的特性,必定都是有其出现的充足的理由的。为啥这么说,因为看它的作用,貌似并不是很大,因为在ES5中已经有运算符是用作比较判断的了:相等==和严格相等===。那么为啥还要新增一个Object.is()呢(~~默默脑补懵逼Object.is()君内心:所以我是为谁存在的呢?),咳咳,让我来解释一下吧!

第一点是ES5的相等运算符和全等运算符有缺点。前者会自动转换数据类型,后者对NaN不友好(NaN君含泪哭诉:懂我的人终于出现了!),而且竟然认为+0跟-0是相等的!(我们明明只是双胞胎好伐?我们要独立“数”权好伐?)

第二是ES6的Object.is()弥补了上一条的缺点。首先它的比较是全等比较,其次是,它为NaN和+0、-0正名了。

哟哟哟,效果图,来一张!


所以,Object.is()君和{NaN,+0,-0}君们热情拥抱在一起了,我们就来贴代码吧!

Object.defineProperty(Object,'is',{
	value:function(x,y){
		if(x===y){ //针对+0等于-0的情况
			return x!==0 || 1/x===1/y; 
		}
		//针对NaN不等于NaN的情况
		return x!==x && y!==y;
	},
	configurable:true,
	enumerable:false,
	writable:true
});

3.Object.assign(target,source):对象合并

有面试经历的人应该都知道Object.assign()有一个非常重要的作用:对象拷贝。然后针对拷贝,我需要说明一点的就是,当源对象是单层对象时,属于深拷贝,当源对象存在对象的嵌套,就是浅拷贝啦。贴上效果图:

 

其实Object.assign()还有很多其他的作用(Object.assign()君:我可是有十八般武艺在身的萌萌哒小能手!):为对象添加属性和方法;合并对象;为属性指定默认值等等。

4.Object实例的__proto__属性

__proto__属性(前后各两个下划线),用来读取或设置当前对象的prototype对象。之所以要在前后加上双下划綫,是为了说明它本质上是一个内部属性,不是一个正式对外的API。那为啥ES6要把它加进来呢?(咳咳,几朝元老级人物了,不能做得太绝呀!)其实是因为得到了浏览器的广泛支持,所以标准规定了,只有浏览器必须部署这个属性,其他运行环境不一定部署。(ES6:既然爱卿们喜欢,真就成人之美,把__proto许配给你们啦!浏览器:我们就呵呵哒了。)所以,我们最好不要用这个属性,而用Object.setPrototypeOf(),Object.getPrototypeOf()以及Object.create()来代替。

在实现上,__proto__调用的是Object.prototype.__proto__,贴代码!

Object.defineProperty(Object.prototype,"__proto__",{
	get(){
		let _thisObj=Object(this);
		return Object.getPrototypeOf(_thisObj);
	},
	set(proto){
		if(this====undefined || this===null){
			throw new TypeError();
		}
		if(!isObject(this)){
			return undefined;
		}
		if(!isObject(proto)){
			return undefined;
		}
		let status=Reflect.setPrototypeOf(this,proto);
		if(!status){
			throw new TypeError();
		}
	},
});
function isObject(value){
	return Object(value)===value;
}

5.实现一个对象继承另一个对象的方法总结:

(1)浏览器特有的__proto__属性:

var prot={a:1,b:2,c:3};
const obj1={
	__proto__:proto,
	foo:123, //ES6特别说明,对象最后一个属性结束是可以带逗号哒,为了动态添加属性方便
}

(2)Object.create()

var prot={a:1,b:2,c:3};
const obj2=Object.create(prot);
obj2.foo=123;

(3)Object.assign()+Object.create()

var prot={a:1,b:2,c:3};
const obj3=Object.assign(Object.create(prot),{foo:123,});

(4)Object.create()+Object.getOwnPropertyDescriptors()

var prot={a:1,b:2,c:3};
const obj4=Object.create(
	prot,
	Object.getOwnPropertyDescriptors({foo:123,})
)















推荐阅读
  • 简述在某个项目中需要分析PHP代码,分离出对应的函数调用(以及源代码对应的位置)。虽然这使用正则也可以实现,但无论从效率还是代码复杂度方面考虑ÿ ... [详细]
  • Ihaveaforminadirectivetemplate:我在指令模板中有一个表单:<formn ... [详细]
  • 使用nodejs爬取b站番剧数据,计算最佳追番推荐
    本文介绍了如何使用nodejs爬取b站番剧数据,并通过计算得出最佳追番推荐。通过调用相关接口获取番剧数据和评分数据,以及使用相应的算法进行计算。该方法可以帮助用户找到适合自己的番剧进行观看。 ... [详细]
  • 本文介绍了闭包的定义和运转机制,重点解释了闭包如何能够接触外部函数的作用域中的变量。通过词法作用域的查找规则,闭包可以访问外部函数的作用域。同时还提到了闭包的作用和影响。 ... [详细]
  • 预备知识可参考我整理的博客Windows编程之线程:https:www.cnblogs.comZhuSenlinp16662075.htmlWindows编程之线程同步:https ... [详细]
  • React项目中运用React技巧解决实际问题的总结
    本文总结了在React项目中如何运用React技巧解决一些实际问题,包括取消请求和页面卸载的关联,利用useEffect和AbortController等技术实现请求的取消。文章中的代码是简化后的例子,但思想是相通的。 ... [详细]
  • VueCLI多页分目录打包的步骤记录
    本文介绍了使用VueCLI进行多页分目录打包的步骤,包括页面目录结构、安装依赖、获取Vue CLI需要的多页对象等内容。同时还提供了自定义不同模块页面标题的方法。 ... [详细]
  • php缓存ri,浅析ThinkPHP缓存之快速缓存(F方法)和动态缓存(S方法)(日常整理)
    thinkPHP的F方法只能用于缓存简单数据类型,不支持有效期和缓存对象。S()缓存方法支持有效期,又称动态缓存方法。本文是小编日常整理有关thinkp ... [详细]
  • 可空类型可空类型主要用于参数类型声明和函数返回值声明。主要的两种形式如下: ... [详细]
  • 1.{#if}{#if|COND|}..{#elseif|COND|}..{#else}..{#if}Examples:{#if2*816}good{#else}fa ... [详细]
  • IhaveawebapplicationthatusesanActiveXCOMcomponent,forexample:我有一个使用ActiveXCOM组件的Web应用程 ... [详细]
  • 表单提交前的最后验证:通常在表单提交前,我们必须确认用户是否都把必须填选的做了,如果没有,就不能被提交到服务器,这里我们用到表单的formname.submit()看演示,其实这个对于我们修炼道 ... [详细]
  • GetWindowLong函数
    今天在看一个代码里头写了GetWindowLong(hwnd,0),我当时就有点费解,靠,上网搜索函数原型说明,死活找不到第 ... [详细]
  • 本文介绍了C#中生成随机数的三种方法,并分析了其中存在的问题。首先介绍了使用Random类生成随机数的默认方法,但在高并发情况下可能会出现重复的情况。接着通过循环生成了一系列随机数,进一步突显了这个问题。文章指出,随机数生成在任何编程语言中都是必备的功能,但Random类生成的随机数并不可靠。最后,提出了需要寻找其他可靠的随机数生成方法的建议。 ... [详细]
  • 不同优化算法的比较分析及实验验证
    本文介绍了神经网络优化中常用的优化方法,包括学习率调整和梯度估计修正,并通过实验验证了不同优化算法的效果。实验结果表明,Adam算法在综合考虑学习率调整和梯度估计修正方面表现较好。该研究对于优化神经网络的训练过程具有指导意义。 ... [详细]
author-avatar
mobiledu2502940393
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有