本文主要介绍JavaScript中的属性描述符、ES6中的模块、箭头函数。JavaScript的属性描述符一、对象的属性属性描述符:目前对象中存在的属性描述符主要有两种形式:数据描述符和访问描述符。数据描述符是一个具有值的属性,它可能是可写的,也可能是不可写的。访问描述符是由getter-setter函数对描述的属性。描述符必须是这两种形式之一,而不是两者。数据描述符(dataattributes)和访问描述符(accessorattributes)都有可选的键值:configurable:当且仅当该属性的configurable为true时,该属性才能从对应的对象中删除,以及是否有除value和writable属性以外的其他属性可以修改。默认为假。enumerable:当且仅当属性的enumerable为true时,该属性才能出现在对象的枚举属性中。默认为假。数据描述符(数据属性)的可选键值:value:该属性对应的值。可以是任何有效的JavaScript值(数字、对象、函数等)。默认为未定义。writable:当且仅当属性的writable为真时,该值才能被赋值运算符更改。默认为假。访问器描述符(访问器属性)的可选键:get:为属性提供getter的方法,如果没有getter则为undefined。当访问该属性时,会执行该方法,执行该方法时不会传入任何参数,但会传入this对象(由于继承关系,这里的this不一定是定义该属性的对象).默认为未定义。set:为属性提供setter的方法,如果没有setter则为undefined。修改属性值时会触发此方法。此方法将接受单个参数,即此属性的新参数值。默认为未定义。注意:如果描述符没有任何value、writable、get和set关键字,那么它将被视为数据描述符。如果描述符同时具有(value或writable)和(get或set)关键字,则会引发异常。2.设置修改对象单个属性说明Object.defineProperty():该方法会直接在对象上定义一个新的属性,或者修改一个对象已有的属性,并返回这个对象。IE8部分支持。Object.defineProperty()语法:Object.defineProperty(obj,prop,descriptor)obj:定义属性的对象。prop:要定义或修改的属性的名称。描述符:将被定义或修改的属性描述符。Object.defineProperty(obj,'val',{value:1,writable:false,enumerable:true,configurable:true})obj.val=2;控制台日志(obj.val);//1Object.defineProperty(obj,'val',{value:1,writable:true,enumerable:true,configurable:true})obj.val=3;控制台日志(obj.val);//3Object.defineProperty(obj1,'val',{get(){num+=1;returnnum;},set(newVal){num=newVal;},enumerable:true,configurable:true})控制台。日志(obj1.val);//2控制台.log(obj1.val);//3propertysetters和getters:使用ES6properties的简洁符号,使用get和set关键字创建访问器属性。constobj={num:1,getnum1(){returnthis.num;},设置num1(newVal){this.num+=1;}}3.设置和修改一个对象多个属性的说明Object.defineProperties():直接在一个对象上定义新的属性或修改已有的属性,并返回该对象。Object.defineProperties()语法:Object.defineProperties(obj,props)/Object.defineProperties(obj,{property:descriptor,property:descriptor})obj:定义或修改属性的对象。property:要定义或修改的属性的名称。描述符:将被定义或修改的属性描述符。变量对象={};Object.defineProperties(obj,{'property1':{value:true,writable:true},'property2':{value:'Hello',writable:false}});四、获取对象属性说明Object.getOwnPropertyDescriptor():返回指定对象上的自身属性对应的属性描述符。(自有属性是指直接赋给对象的属性,不需要从原型链中查找)。IE8支持。Object.getOwnPropertyDescriptor()的语法:Object.getOwnPropertyDescriptor(obj,prop)obj:要查找的目标对象prop:目标对象中的属性名letobj={},obj1={};Object.define(',{value:1})obj1.num=1;console.log(Object.getOwnPropertyDescriptor(obj,'num'));//{value:1,writable:false,enumerable:false,configurable:false}控制台。日志(Object.getOwnPropertyDescriptor(obj,'num'));//{value:1,writable:true,enumerable:true,configurable:true}参考自:MDN--Object.defineProperty()MDN--Object.defineProperties()MDN--Object.getOwnPropertyDescriptor()ES6module1.定义moduleModule函数主要由两个命令组成:export和import。export命令用于指定模块的对外接口,import命令用于导入其他模块提供的功能。2.导出命令1)定义:模块是一个独立的文件。文件内部的所有变量都无法从外部获得。只有通过export关键字将变量、函数或类导出,外部才能读取该变量、函数或类。种类。2)注意事项:a,export命令指定了对外接口,必须和模块内部的变量建立一一对应关系,所以不能通过export直接输出变量或值b,export命令必须在模块的顶部,而不是在块级范围内导入也是如此。这是因为在条件代码块中,没有办法做静态优化,违背了ES6模块的设计初衷如何使用://output1exportvara=1;//输出2varb=1;变量c=2;导出{b,c};//写法不对,因为没有对外提供接口vard=3;出口d;出口1;3.exportdefault命令1)定义:为模块指定默认输出,无需import知道原模块输出的变量名,可以使用任意名称指向模块输出内容可以使用一次,否则会报错b。exportdefault本质上就是导出一个名为default的变量或方法,然后系统允许你给它取任何名字。后面不能跟变量声明语句使用方法://输出一个变量vara=1;出口违约;//输出一个值exportdefault1;//导出一个方法exportdefaultfunciton(){}//导出一个方法functionadd(){}exportdefaultadd;//输出一个对象exportdefault{}4.导入命令1)定义:使用导出命令定义模块的对外接口后,其他JS文件可以通过导入命令加载该模块2)注意事项:a.在加载export输出的变量、函数和类时,需要使用import命令接受一对大括号,指定要从其他模块导入的变量名。大括号中的变量名必须与导入的模块相同。外部接口名称相同(import{variable}from'./index.js');加载export默认输出的变量、函数、类时,可以使用任意名称指向输出方法,import后不要使用大括号(importallFnfrom'/index.js')b,加载所有输出模块的值,用星号(*)指定一个对象,所有的输出值都加载到这个对象上,包括exportdefaultc,import命令输入的变量只是Read,不是允许重写加载模块内部的接口。只有当输出是一个对象时,它的属性才可以改写d,import命令有提升作用,会被提升到整个模块的头部,最先执行。导入命令在编译阶段执行。在代码运行e之前,如果重复执行同义import语句,只会执行一次,不会执行多次。多次使用import引入同一个模块的不同方法时,被导入的方法对应一个模块,import语句为单例模式f,import是静态执行的,所以不能使用表达式、变量、条件语句、代码输入blockg和import时,语法要求不带as(exportdefault输出)的默认值始终在顶部使用。方法://执行加载的模块,引用它的模块无法获取它的任何信息import'lodash';//通过exportimport{firstName}from'./index.js'加载变量输出;//加载exportdefault输出的变量importallFnfrom'./index.js';//在一个import语句和其他接口中同时导入默认方法import_,{each}from'./lodash';//加载模块所有的输出值,使用星号(*)指定一个对象,所有的输出值都加载到这个对象上import*ascirclefrom'./index.js';//单例性能//test1.jsvara=1;导出函数add(){a++;控制台日志(一);}//test2.jsexport{add}from'./text1.js';//index.htmlimport{add}from'./test.js';import{addasgetCount}from'./test1.js';添加();//2获取计数();//35.as关键字:1)定义:使用as关键字重命名输出或输入变量2)注:as关键字前面表示原名,后面是新名称(oldNameasnewName)usage://输出时重命名vara=1,b=2;export{aasnum1,basnum2}//在导入时重命名import*asnumModulefrom'./index.js';//renameonimportimport{xasnum1}from'./index.js'6.export和import的复合用法1)定义:在一个模块中,同一个模块先输入后输出。导入语句可以和导出语句一起写2)注意事项:a。export和import写在一行时,接口实际上并没有导入到当前模块中,而是相当于把接口转发给外界,当前模块不能直接使用接口b。export和import结合使用时,*代表所有其他接口(export输出),不包括默认接口(export默认输出)使用方法://先使用一个//输入,再输出其他接口(export输出)),foo和bar不能在这个模块中使用export{foo,bar}from'./index.js';//其他模块使用import{foo,bar}from'./util.js';//使用两个//其他接口的整体输出(export输出)export*from'./index.js';//在其他模块中使用import*asallfrom'./util.js';//使用三个//先输入后输出默认接口(exportdefaultoutput),不能在本模块使用该方法export{default}from'./index.js';//在其他模块中使用importallFnfrom'./util.js';7.跨模块使用定义:一个模块中的接口跨越多个文件使用方法://test1.jsexportconstA=1;//test2.js导出常量B=2;//合并index.js中的所有接口export{A}from'./test1.js';从'./test2.js'导出{B};八、ES6模块的好处1)ES6模块可以按需加载。加载时,只加载import命令输入的方法和变量,不加载模块中的其他方法和变量。这种加载称为“编译时加载”或静态加载,即ES6可以在编译时完成模块加载。而CommonJS和AMD模块只能在运行时确定模块的依赖关系和输入输出变量,也就是“运行时加载”,因为这个对象只能在运行时获取。比如加载CommonJS模块时,本质上是整体加载,生成一个对象,从对象中读取加载方法。2)不再需要UMD模块格式,以后服务器和浏览器都会支持ES6模块格式。目前通过各种工具库,实际上已经做到了这一点。3)以后浏览器新的API可以以模块的形式提供,不再需要做成全局变量或者navigator对象的属性。)不再需要对象作为命名空间(例如Math对象),这些功能将来可以由模块提供。9.ES6模块注意事项ES6模块自动采用严格模式。严格模块通常只有两点需要注意。一是变量在使用前必须声明,二是顶层的this指向undefined。10、脚本和模块的区别脚本的特点:1)是JavaScript源文件的一种2)通过中加上async(一旦脚本下载完毕,渲染引擎会中断渲染,执行完脚本后再渲染),defer(脚本要等到整个页面在内存中正常渲染,也就是DOM结构完全生成,之后其他脚本执行)属性让它异步加载模块特性:1)是一种JavaScript源文件2)浏览器异步加载type="module"的标签的defer属性。如果有多个中设置async属性。此时只要加载完成,渲染引擎就会中断渲染并立即执行,执行完成后恢复渲染。一旦使用了async属性,的中间,语法行为与加载外部脚本完全相同。里面可以使用import、export、export默认命令5)兼容性不好,IE不支持,Edge16支持参考:ES6阮一峰--模块语法ES6阮一峰--模块加载实现箭头函数特点1.Arrow函数的特点1)函数体中的this对象是定义时的对象,而不是使用时的对象。这个点的固定不是因为在箭头函数内部绑定this的机制。实际原因是箭头函数根本没有自己的this,所以内部的this就是外层代码块的this(也就是this的指向提升了一个类)。正因为它没有this,所以不能作为构造器使用。2)不能作为构造函数使用,即不能使用new命令,否则会抛出错误。3)不能使用arguments对象,函数体中不存在。如果要使用它,可以使用rest参数代替。4)不能使用yield命令,所以箭头函数不能作为Generator函数使用。5)箭头函数没有自己的this,所以不能用call()、apply()、bind()方法来改变this的方向6)箭头函数中没有arguments、super、new.target,它们指向相应的外部函数变量。2.将箭头函数转换成ES5代码//ES6functionfoo(){setTimeout(()=>{console.log({'id',this.id});},100)}//ES5functionfoo(){var_this=这个;setTimeout(function(){console.log('id',_this.id);},100)}来源:阮一峰ES6介绍--箭头函数以上内容如有错误,希望大家指出,谢谢.
