!function跟(function(){... })()函数意义相同,叫做立即运行的匿名函数(也叫立即调用函数)。
js中可以这样创建一个匿名函数:
(function(){do something...})()
//或
(function(){do something...}())
而匿名函数后面的小括号()是为了让匿名函数立即执行,其实就是一个函数调用。
这样写会报错:
function(){alert(1)}()
因为function前面没有(或者! ~之类的运算符,js解析器会试图将关键字function解析成函数声明语句,而不是函数定义表达式。
作为组运算符,小括号()会将其内部的表达式当成一个整体,然后返回结果,所以定义一个匿名函数正确的格式就是用小括号将函数体括起来。
同样的! ~ + -等运算符也有同样的效果,这是因为匿名函数也是一种值,这些运算符会将后面的函数体当成一个整体,先对匿名函数进行求值,然后在对结果进行运算。
不过这些运算符虽然能够达到让匿名函数立即执行的目的,但是要小心他们是有副作用的,比如:
!function() {return 1}()//false
~function() {return 1}()//-2
-function() {return false}()//0
-function() {return false}()//0
没错,他们会对函数的返回值进行运算,这样可能会导致最终的结果和你想要的结果不一样。当然,对于那些没有返回值的函数来说,当然是没有什么影响了。
扩展资料:
匿名函数的调用:
var abc=function(x,y){
return x+y
}
alert(abc(2,3))// "5"
上面的操作其实就等于换个方式去定义函数,这种用法是我们比较频繁遇到的。
例如我们在设定一个DOM元素事件处理函数的时候,我们通常都不会为他们定名字,而是赋予它的对应事件引用一个匿名函数。
使用()将匿名函数括起来,然后后面再加一对小括号(包含参数列表)。
alert((new Function("x","y","return x*y"))(2,3))// "6"
参考资料来源:百度百科-JavaScript
immutable,副作用,纯函数关键词解释:
js 中的对象一般是可变的,因为使用了引用赋值,虽然可以节约内存,但是会有一些隐患。一般做法使用浅拷贝和深拷贝来避免修改,但是这样会造成 CPU 和内存浪费。
为了解决这个问题,出现了 immutable.js 和 immer
immutable.js 实现原理: Persistent Data Structure (持久化数据结构)。
内部实现了一套 Persistent Data Structure,还有很多易用的数据类型像 Collection 、 List 、 Map 、 Set 、 Record 、 Seq 。有非常全面的 map 、 filter 、 groupBy 、 reduce``find 函数式操作方法。同时 API 也尽量与 Object 或 Array 类似。
缺点:
和 redux 的配合使用,redux 简化了 Flux 中多个 store 的概念,只有一个 store,数据操作通过 reducer 使用。reducer 就是要接受一个纯函数。
mobx 作者写的一个 immutable 库,核心实现利用 es6 的 proxy。
immer 使用原生数据结构的 api,而不像 immutable-js 转化为内置对象的 api。
学习成本低,就是把之前的操作放置到 produce 函数的第二参数函数中去执行。
原理:使用了一个 ES6 的新特性 Proxy 对象。深层嵌套对象的结构化共享的处理
proxy 具体可以看 Proxy
Proxy 无法 polyfill,所以 immer 在不支持 Proxy 的环境中,使用 Object.defineProperty 来进行一个兼容。
immer 维护一份 state 在内部,劫持所有操作,内部来判断是否有变化从而最终决定如何返回。
可以不用考虑清除内存的事情,因为javascript自带垃圾回收机制。JavaScript语言是一门优秀的脚本语言。其中包含脚本语言的灵活性外还拥有许多高级语言的特性。例如充许构建和实例化一个对象,垃圾回收机制(GC:Garbage Collecation)。通常我们使用new创建对象,GC负责回收对象占用内存区域。因此了解GC,可以加深对javascript垃圾回收机制的理解。
GC在回收内存时,首先会判断该对象是否被其它对象引用。在确定没有其它对象引用便释放该对象内存区域。因此如何确定对象不再被引用是GC的关键所在。