分享web开发知识

注册/登录|最近发布|今日推荐

主页 IT知识网页技术软件开发前端开发代码编程运营维护技术分享教程案例
当前位置:首页 > IT知识

JS 模块 p6

发布时间:2023-09-06 02:32责任编辑:熊小新关键词:暂无标签

利用了闭包的模块:

简单模块例子:

function fn(){ ??var x = 1; ???function y(){ ??????console.log(x); ???} ???????return { ?y:y}}
var do1 = fn()

do1.y(); ??// 1

我们可以将这个“对象类型”的返回值看做是 模块的公共API 
这个例子中返回的实例中 y() 等于是拥有了函数fn的内部作用域的闭包。

模块模式条件(书):

1.必须由外部的封闭函数,且被调用。

2.封闭函数必须返回至少一个内部函数。

单例模式(平时使用的比较多):

var single = (function(){ ???var x = 1; ???function fn(){ ???????console.log(1); ???}; ??????return { ?fn:fn ?}})();single.fn();//1

将模块函数使用IIFE 表达出来,因为是立即调用,所以此实例的标识foo为单例。??

还有一种在初始化html的时候使用的也比较多,如下:

(function(){  var u = {};  u.x = function(a){    ???console.log(a);  }  window.$custom = u;})();$custom.x(1);//1

使用IIFE 立即给window动态增加一个属性,$custom,因为window的变量和方法是可以隐去的,我们可以直接调用$custom实例引用的方法x,最终打印1。

动态修改(返回实例引用中fn与fn2都用于内部作用的闭包,所以可以在外部通过调用fn2,动态修改内部id的值):

var foo = (function(){ ?????var id = "hhh"; ???????????function fn(){ ??????????console.log(id); ?????} ??????function fn2(){ ??????????id = "MM" ?????} ??????return { ?fn:fn ,fn2:fn2 ?}})();foo.fn();//hhfoo.fn2();foo.fn();//MM

当然了,你可以更改函数或者增加新的实例方法(之前的文章中有写 JS 创建自定义对象的方式方法)

再来一个(引用书中的例子):

var foo = (function x(){ ???var module = {}; ???function def(name,arr,impl){ ????????for(let i = 0;i<arr.length;i++){ ??????????????// 重新定义数组中的对象 ??????????????arr[i] = module[arr[i]]; ????????} ????????module[name] = impl.apply(impl,arr); ???} ???????function get(n){ ???????return module[n]; ???} ???return {def:def,get:get}})() ???

定义一个先:

// 返回一个模块对象实例foo.def(‘test‘,[],function(){ 
   ???function h(n){return ‘我是test内部的h函数‘+n} ????return { h : h };});foo.get(‘test‘).h(‘hi‘); // 我是test内部的h函数hi// 返回方法函数本身foo.def(‘test‘,[],function(){ ????function h(n){return ‘我是test内部的h函数‘+n} ????return { h : h };});foo.get(‘test‘)(‘hi‘); ?// ?我是test内部的h函数hi

两种方式,第一种内部module的get 返回一个对象实例,含有h内部函数,可以调用;

第二种返回h函数本身,通过  ‘()‘ 直接调用即可。

再来一个,多重调用(在上面给module定义了test后,再来一个并且利用回调函数调用test)

foo.def(‘test2‘,[‘test‘],function(callback){ ????function j(){ ????????console.log(callback.h(‘hihihihi‘)+‘其实我是test2‘); ????} ?????????????return { j:j }});

foo.get(‘test2‘).j();//我是test内部的h函数hihihihi其实我是test2

我们来分析一下,在foo.def 方法中核心的时候这句 apply(有关apply 、call和blind方面以后再表),简单说一下,apply方法把作用域第一个参数的作用域绑定或追加到调用的对象中,从何绑定this,并执行改方法,第二个参数就是执行这个方法需要的参数。

那么我们在调用def时,就是给foo中的内部对象module增加了一对键值对,module.name = impl()    这里得到impl函数执行后返回值

在调用get的时候,得到这个值,在第一个def中是test返回是 {h:h} 对象实例(调用foo.get()),所以我们使用 foo.get(‘test‘).h() 就调用了返回实例中的h函数,而h函数拥有访问h所在的作用域的闭包。

再来看第二个def,test2:

第二个def时我们给到3个参数,test,[test2]和一个匿名函数

foo在执行def方法时,首先循环数组,并重新对数组中的值进行重新赋值,这个例子中是 module[test],等于是得到了def1中的{h:h} 对象实例,然后调用apply方法,执行定义的匿名函数,返回值为 {j:j}

并且j方法中的callback 其实就是{h,h} ,(是这样的  module[test2] = impl.apply(impl,{h:h}) ),明白没?

所以foo中的内部对象 module又获得了一对简直,module.test2 = { j:j }  ,并且j中的callback 是 {h:h}

最后我们通过  foo.get(‘test2‘) 获得了{j:j} 然后执行 j() 方法,并成功打印  “我是test内部的h函数hihihihi其实我是test2”。

此处在test2中,j()方法拥有作用域的闭包,也就是说可以访问到callback,而callback实际上在此事{h:h},而h也拥有其作用域的闭包。

可以说,这就是一种模块的表现方式或者说闭包的应用。

关于es6对模块有了重新的定义,再次我简单记录一下:

// test.jsfunction h(){ ?return ‘ggggg‘}export h;// test2.jsimport h from ‘test‘;function j(){ ??console.log( ?????h(); ??)}export j;// foo.jsmodule test from ‘test‘;module test2 from ‘test2‘;console.log( ???test2.h();)test2.j();

关键字:

import: 将一个模块的一个或者多个API 导入到当前作用域

export: 将当前的一个标识符导出为API

module: 将模块的API 导入并绑定到一个变量。

JS 模块 p6

原文地址:https://www.cnblogs.com/jony-it/p/10337709.html

知识推荐

我的编程学习网——分享web前端后端开发技术知识。 垃圾信息处理邮箱 tousu563@163.com 网站地图
icp备案号 闽ICP备2023006418号-8 不良信息举报平台 互联网安全管理备案 Copyright 2023 www.wodecom.cn All Rights Reserved