00:00
大家好,我是学习力的特约讲师高洛峰,上节课呢,咱们看了对象的新语法,也就是ES6给我们引入了class,也就是类的这样的一个概念,包括构造方法呀,继承啊,Super啊,然后杰森呢,有一些简化的方法,那这节课呢,我们来学习一个更重要的一个概念,也就是我们现在都普遍应用的模块化编程,那什么是模化编程,有什么优缺点呢?因为我们现在在编程的时候,我直接用例子给大家讲解啊,在编程的时候经常会有多人去写程序,或者是你在写程序的时候,经常会引入第三方的一些文件,对吧?那避免不了就会有一些同样的命名方法,同样命名函数同样命名,那方法同命名函数同样命名,就会引起这样的命名冲突,对吧?那如果不拆分模块的话,都在一个文件里面写的,这个文件又太长,所以呢,肯定是拆开多个模块去编写的,对吧,那么比如说我们这里边。咱们就新建几个,比如新建加S文件叫one.ds一个文件,这是第一个人写的,比如说里边实名一个呃,Light name等于张三,随便写一个Y,年龄等于呃20这样情况,然后之后再做一个方法Y,比如说ad的方法,声明一个XY相加,然后返回X加Y这样的一个结构,那比如说我们这里边还有另外一个人。
01:18
对吧,写了一个程序。嗯,新建一个GGS件。嗯,叫做to吧,To点加S,你看这个文件那里边,比如说他也声明了一个内一个方法,你比如说叫做李四,李四,然后呢,它这里边也声明了一个,嗯,声明一个变量,当然变量长的什么都可以啊,声明一个比如说相乘的一个方法XY,然后这里边返回X乘以Y这样一个情况,然后呢,我们在主程序里边,比如说这块又有了一个主程序。index.gs。点J错了,不是JT文件啊,建一个加速串文件,我们这块建一个in,该点JS的一个这样的文件,那这里边比如说我们调用刚才那两个文对吧?或者这里边我们也生明一个变量,呃生明一个A等于100,就随便先写一个,那我们看怎么使用呢?因为我现在这个没有考词,没有那个外派那种,呃打包,所以呢,没有那个打包的话,那我就得在主程序里边引用对不对,那我新建一个比如说呃模块,那我们就建一个而加文件MOU Mo model的一个ML文件在这里边,如果我想引用那几个文件的话,那我们怎么引用呢?比如说script ss通过SR7引用一个one.gs对不对,然后引用一个假如说这是程序这块two.s然后这块再引用一个带点GS这么去引用,那现在这么引用的时候,肯定有命名重突的问题,那我们。
02:50
运行一下F12,你看这里边name已经被定义了,不能重新定义对不对,第一个它就错误了,所以呢,咱们经常在使用别人的文件的时候,引入别人的JS,对吧?在这个JS里或者在这里用,通常都会有这样的问题,那怎么解决这样的问题对吧?我们肯定写成要分多个文件的,对吧?那每一个文件我们把它当成是一个模块。
03:09
怎么用呢?那我们在这里边加上什么?加上类型等于model,所有的类型都加上model,加上model,所有的类型都加上TYT类型model加上model之后,那每一个你导入的这个,每一个你加载的这个文件,那相当于都变成一个模块了,模块和模块之间就是独立的了,就相当于把它们锁在一个房间里边,这是单独的房间,这单独房间,这单独房间三个模块,虽然加载这三个模块,但是这三个模块呢,各自独立,里边有自己的作用率,那每个人在这里边写的变量就不会冲突了,那我们程序也就不会出错了。你看一下程序就不会出错了,变成模块就不会出错了,那变成模块不会出错了,但是这里边儿我能用到,你比如说在index里边,我能用到这里边的,呃,你比如说这个相乘的方法,或者是这里边的什么,这里边儿添加的方法吗?我能用到吗?
04:05
你看如果想用这些文件,它现在它也用不了,我比如说我在index里边在这吧,我在这块使用一下,假如说我使用添加的方法,你看啊,添加十和20返回点rog,我大一下你看可以使用吗。他会告诉我找不到这个方法。你看它没有定义,那明明我在这个in代之前,我们在这里边已经包含了one和two这样的方法,那为什么我们找不到呢?因为你封装在独立的模块里了,这模块里边所有东西是不被不向外暴露任何东西的,封装在里边了,这才能保证变量不冲突,但是呢,你也用不了,如果想使用,那我们就得用到我们这节课需要学到的,通过这个命令来规定模块对外的一个接口,你想要这个文件里边变量也好,方法也好,类也好,想要外边去访问,你就将这个暴露,比如说我现在想用这个方法让别人使用去使用,就是ex pot,我只要加一个这个怎么着将它导出,导出之后,那么我们在某些程序里用的候,在这里用的时候,那其实我们在这里边这两个其实就我就不用加了,对吧,直接加在一个JS就行了,对吧,因为在这里边其他的它都是模块方式的,然后我们在这里边,比如说。
05:19
已经使用这个了,但是呢,我们虽然这块暴露了,暴露出去了,你这块导出了,我们这边想用的话,就得来个导入,导入怎么用呢?用这个关键字I按port导入,你看我用这个,呃,结构赋值的一个方法,你看啊from从哪个文件里导入呢?从当前目录下的里边吧,这个A应该是在万里边吧,你看万里边,那我从这个万里边。啊,它可以省略这个GS啊。从这个JS文件里边导入什么呢?你看这个大家如果不理解,我不这么写,你看让大家理解一下啊,我先一步一步来,我不在这边写,你看我们用这个e putt导出,导出什么呢?我可以写一个接森的格式,你看啊,这里边我可以把咱们刚学过那个接森的一个简写,把名字导出,年龄导出方法导出,你看如果名字相同的这样对吧,是不是可以简写对吧?那这个名字相同的冒号ADE是不是可以这样简写对吧?那ad。
06:20
一个变量原和方明相同,是不是可以解解,你看我这么将这三个都导出,将这三个都向外怎么着向外暴露就一起暴露,当然你可以一个一个暴露,也可以这样怎么着一起把它所有的东西怎么着都暴露出去,那现在都暴露出去,这是不是就是一个对象对吧?那我们在这里边在导入one的时候,From,你看对象这里边接收,咱说两边结构一样,我这块是不是就能生明几个变量相接收,那对象格式导出的时候是这样。对象,那我名字是不是得跟它相同啊,你看名字是不是也相同,所以呢,我这里边忘了这里边叫什么名字了,一个name,一个age,一个ad,你看啊,如果我就要name,可以单独要一个对不对,那导出多个,那我可以直接就要ad,你看现在。
07:02
我们打一下。这个他这块得在那个的,就是这个这里边工自动加这个。来导出这个文件,那30就可以了。嗯,在那个那个外派里边,我们是可以省略的啊,这里边云那里边有帮我们处理的插件,这里边没有帮我们处理,所以呢,我们得手工的加上这个JS文件,你看这就是我们使用的一个原理,一个里边导出,然后我们用的时候导入就可以用这里边了。导入就可以了,那假如说我这里边方法里边,假如说也有一个叫ad点,那有的时候你不说能解决这个命名冲突的这个问题吗?能解决命名冲突的问题吗?那我们在这块假设我再导入iport,导入一个ADD,最后我从哪里边from,从这个库里边点DS,有可能你用别人代码里边的方法名是相同的,而我们用的时候这种结构赋值,你必须得跟这种导出的这个名字是相的,对不对,这里边我们还没导出,我们在这块这么导出也是也相也行啊,也是一个跟刚才的结构是一样的,你看那我们现在调用的时候,它是调用的这个还是调用那个呀,相乘还是怎么的,然后相同的名字会不会有冲突呢?那告诉我它已经定义了,肯定不行,那我们可以怎么办呢?我们可以在导入的时候用这种结构赋值,我们还可以起个别名mull,然后我们名字就不冲突了,然后我再调一下,比如说ull,呃里边我们调用一个呃三和5.logg来我们试一下。
08:36
短信你看。三十十加二十三十三五一十五就可以了,所以呢,导入两个文件,两个文件里边虽有命名相同的,在我们在使用的时候,一看名字相同了,对吧?在我们使用的这个环节中,名字相同了,我们可以起个别名,这是没问题的,这就是导入导出,当然了,不光是这一种办法,那我们就看一下导入导出,它可以有几种方法,那一种呢,就是我们在声我们不用这种声明的时候,你看这种是将你这个页面里边所有的,你可以一起声明导入导出出去。
09:04
导入导出去,那就是导出去啊,我还可以怎么的,比如说把它注掉,我可以一个一个的导出,比如说我这里边只用到这个了,其他的没导出,那我们就esport导出。就可以了,刷新一下,你看是一样的,这是单个导出,那我比如说我这个变量为导出,或者常量也可以导出,比如说esqt导出都可以,或者是我这里边不光是能导出对象,比如说方法,咱们刚才也看导出了,那我还能可以导出导出对象ESQT3个导出啊,比如说class,嗯,声明一个,呃,我们叫person吧,Person啊,这是一个类名,不能加括号了,比如构造方法,然后这里边构造方法。对吧,这里边我们再写一个以的这样的一个方法,我这会就随便打一个,这是一个test的测试点rog,你看导出这个,那这个名字叫person,那我们在接收的时候怎么办呢?是不是你看在导入的时候,我可以在任意地方在port导入什么呢?我可以这样名字如果一样的话,就叫person就行,这么导入它直接结构赋值,就相当于生成了一个这样的一个,呃,结构跟原来的是一样的from。
10:12
点斜杠,我写在了one里边还是图里边,呃,写在了one里边对不对?然后one.ds导入,你看iPod,然后这里边正常使导入这个类的结构,那正常使用就行了,Cost生明一个,呃,P对象等于new person new person,然后调用P里边的以Y的方法,你看怎样可以调用。刷新一下,那这是一个测试就可以了,所以呢,我们可以一个一个的使用这种方式导出,那我们在用的时候,哪个文件你导出都行,怎么导出都行,对吧?然后你就加载就行了,可以任意个位置用一次你导入一下,另一次导入一下也都可以,对不对?或者在整个文件的最上面一起导入,然后使用也都行,导入一下,用一下这个名字吧,对吧?那你如果这里边都这么用的话,比如说我把这个去掉,导入多个,因为它在那个one里边吧,你想就用一个文件的话,那PSO,这也是行的,对吧?一起导入没有顺序关系,只要名字一样就行,这是咱们刚讲过的结构赋值应用的一种方式就可以了。
11:09
那我们再看几个几个细节,想象一下,如果我们在这个方法里边,我们在导入这个方法了,那么我们在使用这个方法的时候,那就必须和这个名字相同,当然了,你可以起这名对不对?那么我们能不能做一个比如说方法函数也行,对不对,让我们在使用的时候自己定名,定义名字呢?可以加上一个底部,就是缺省的,就在这块我们声明的时候不起名字。然后你自己去起名字去对吧,缺省的你可以试什么变量啊,常量什么的都可以,比如说声明一个方法,那方法比较特殊,声明方法那方法你都不用起名字,这样就行了,比如这里边我只需要一个参数lgs,那我就打一下这个参数ARGS.rog。这样打印参数,你看缺省的时候暴露这个名字,那如果我们是方法是有名字的话,方法是有名字的话,那我们说在用的时候必须用这个名字对不对,那我们是import,比如说大块起一个什么ad的一个名字啊from对吧,然后点斜杠to.gs拿过来对不对,然后调用这个方法。
12:12
对吧,那没有名字怎么办呢?那我们这块就不用大括号,或者在大括号里边一样,对不对,起边边一样,你可以在这块自己写名字,你比如这个方法我们叫做P,假如叫做杂印P,对吧X吧,随便写一个,那我们就可以直接现在在调用了PX,然后我们在这里边打印hello word。随便写一个,你看。刷新一下。啊,只多了一个什么,多了一个I啊,这块有定义一个I嘛。你看hard就给我们打印出来了,就用这个,也就是我们可以在导出的时候,你不指定任何名字的时候。对吧,然后其他地方使用就可以了,但是能不能导出两个莫名名字呢?比如说我这块导出一个变量light,嗯,A等于100,这样你看。
13:05
直方形de fatut,如果我单独导出,你看导出这一个Y加A等于100。嗯,这怎么有个下划线,算了,不用这个,假如说我们再导出一个另外的一个一个函数吧,就外边起名字吧,对吧,随便再找一个,如果两个你看我都导出。啊,就会出现一个什么问题呢,我们因为你这边使用缺省的这个名字交给导入方,对吧,使用这个名字交给导入方,那它起的名字是对应的,这里边的哪一个呢。他就不知道了,所以呢,你有缺省导出的时候,缺省导出的时候,特别是方法呀,或者累呀,对不对,那累的时候也不用起名字对吧?那。学生导出的时候怎么的,他就不知道,引用的时候就不知道你用的是哪个,因为这块名字就给它自己定义了吗?不然的话,你看我们里边叫什么名字,我们外边导入的时候就需要叫什么名字,对吧?当然可以通过起别名这种方式去改,对吧。
14:04
但是也比较麻烦,所以呢,记住缺省导出的时候,一个页面就是一个文件只能有一个一个模,诶一个模块中只能有一个使用eqtf,嗯,Det只能有一个,这样的话用外边叫名字就可以了,这要说明的是这个,那另外我们在使用的时候。你比如说在这里边,我们都一个一个的导入,对不对。这种一个一个导入,当然我们可以不不用一个一个导入,你看在这里边我们导出的在本身在这里边我们能不能调用这个方法呢?比如说ad调用,它虽然导出了,但我这里边直接也是一个应用程序,可不可以呢?你看XY不是XY啊,一百二百这么调用一下,然后我们点rog。你看导出是要外边用,那本文件能不能用,我现在跟你说的是这个事儿,你看一下可不可以呢?300当然可以用了,导出去可以用,意思是暴露出去,但是自己也能用,明白这意思吧,这是没问题的啊,那现在假如说我不想这么导出,我想整体导出,你看啊。
15:12
这款。这块不想一个一个导出。咱们用的最多的就是什么,就是最开始我给大家写的那种写法,怎么导出呢?E pot导出整体的一个,那导出什么,把这里边你想导出什么,对吧?在一个导出,比如说我想把名字这块right删掉啊,把名字导出,把什么年龄导出,把person导出,把这个,呃,这里边就A,还有一个什么,还有个addd ADD DD导出,把这些都导出,你看那我们在这块使用的时候,我们可以用这里边某一个,有万里边的用某两个对不对,当然变量什么也都可以用,现在也是没问题的,你看啊。也是没问题的,那我能不能不这么使用呢?我在这页面用的时候就是多了注意这啊。
16:01
我能不能一起全拿过来呢?可以,你不用一个一个起名字对不对,那里边导出的我就全用对吧,那import导出我们可以用一个什么星,我们可以起一个别名这样。我们用星相当于所有的导入,所有的导入你得起个名放在一个对象里,对不对?用as,这就是起别名了,比如说起一个别名叫做嗯。叫做one吧,From从哪块呢?从那个one当前目录下one.ds里边导入的,然后我们用的时候怎么用呢?用这个名称就不是直接用变量了,比如说我调用这里边儿的。有个ADB的方法对不对,那我怎么用呢?那就是使用one.one点呃,ADB使用这个,然后点log打印一下,这里边我们传一个一传一个二,一加二对不对,我们看一下结果你看啊三对不对,那300是那个导入那个文件的,这样的话我们调一个就可以,就可以使用对象这个去调用,那同样可以调用这里边导出的任何一个文件。
17:04
可以调用这里边导出的任何的一个,刚才咱调用的是ad嘛,对吧。都可以,那假如说我们为了防止别人在使用的时候名词冲突,那我们其实可这这里边儿我们也可以起名字的,起个别名了,比如说my name,用as给它起个别名,导出的时候起别名,那我们在使用的时候呢,就不需要别名了,比如说iport,那我们导入的时候呢,这里边当然也在这个one里边了啊,那我们直接one.my name.b我们用的时候就用它起的别名了,咱们在这块可以起别名,像上边我们用的时候。也可以起别名,对不对,这块也可以起别名,里边起起别名,导出的时候可以起别名,导入的时候也可以起别名,是两个都可以啊来我们刷新一下,你看就可以了,这就是我们模块化编程的一个,呃,基本的语法其实就这么多,非常的简单,那我们再总结一下。模块编程导出的有多种方法可以,呃任你只要是在这个模块里边声明的任何一个都可以导出,不管是变量,常量,方法类都可以导出,咱们都是了,可以单个一个一个的导出,导出的时候也可以起别名,也可以最终一起导出,还可以有一个什么,还可以有一个文件里面还可以有单独的一个缺省的导出,交给导入方去写名字,那导入的呢,对吧?用于输入其他模块的功能,可以用接收一个大块,用结构赋值那个帮我们一个一个的接收,对吧?那名字呢,跟那个对应,如果不想对应的话,你也可以起别名。
18:25
所以怎么用都行,比较灵活的一种方式,所以呢,我们用这种,呃,模块化它的优点就是什么呢?就是用我们之前写的代码的时候,写的代码呢很多,那有时候呢,可能是一个项目里边有很多JS,又有好几遍,对不对,那如果加在以前的那种JS代码的话,那整个页面都要加载进去,很不利于优化,那JS呢,现在呢,给了我们一个这个方法对不对,那每一个GS文件之间呢,可以相互调用其他JS里边代码。但这个调用呢,又不是随意调用,那选择把自己的一部分变量或者函数给别人调用,那调用别人的代码的人呢,也要清楚你调用别人的什么函数和什么变量。
19:02
对吧,就跟我们去要去什么图书馆借书一样,那图书馆呢,给你提供你可以借阅的一个目录,你选择你要看的书籍,然后再去借阅,那再有一个好处就是在打包的时候。那虽然它的模块文件里边有1万行,但他只暴露出去十几个变量,那我们打包的时候呢,就将这个十几个变量我们打包在一起,其他的呢,就基本上到无用代码给去掉了,这也是一个好处,所以呢,用这个我们可以减少命名冲突啊,避免引入时的层层的依赖啊,可以提升我们的执行效率,这就是我们模块化编程的优势。好,谢谢大家,这节课我们就讲。
我来说两句