美文网首页
前端闭包,私有变量,this,单例等。

前端闭包,私有变量,this,单例等。

作者: 平谦 | 来源:发表于2017-07-11 21:02 被阅读81次

函数
function funcName(arg0, arg1, arg2){}
console.log(funcName.name)//funcName(函数的名字)
console.log(funcName.length)//3(参数个数)

递归
在递归时, 可以用arguments.callee代替自身函数名, 这样就可以解耦, 随意修改函数名
function factorial(num) { if (num <= 1) { return 1; } return num * arguments.callee(num-1);}

闭包
闭包会携带包含它的函数作用域, 所以它所占的内存逼其他函数多, 建议尽量少用; V8引擎会尝试回收被闭包占用的内存;个人理解: 没有闭包这东西, 无非就是作用域导致的现象, 也可以说任何函数其实都是闭包

闭包与变量
本来有一个需求是, 调用createFunctions()1
函数就返回对应的索引的值, 也就是1, 但是结果却是10; 因为这个函数返回的是一个闭包;这个闭包又要返回i, 但在它自身的作用域里无法找到这个变量, 它就会去作用域链上查找, 但是作用域链上的i, 最循环结束后, 已变成10了; 所以调用任何一个闭包,都是指向同一个作用域链上的i, 其值为10;

function createFunctions() { var result = []; for (var i=0; i < 10; i++) { result[i] = function() { return i; }; } return result;}createFunctions()1//10

可以修改为如下, 将i通过函数的方式传递进去, 那么num就是i的副本, 它的改变不所i而改变;因此当调用createFunctions()1
时, 需要返回num, 再其自身作用域里没有num, 就往上一级作用域里查找,正好可以找到num, 并返回, 其值也是和外层循环时传递进来的值一样;

function createFunctions() { var result = []; for (var i=0; i < 10; i++) { result[i] = (function(num) { return function() { return num; } })(i) } return result;}createFunctions()1//1

内存泄露
在ie9以前的浏览器dom节点是使用计数引用的方式管理回收内存, 因此不合理利用闭包会导致内存泄露;下面这个函数onclick的闭包函数, 引用了elemnt.id, 所以导致element无法被回收

function assignHandler() { var element = document.getElementById("someElement"); element.onclick = function() { alert(element.id) };}

可以将代码改成如下, 避免泄露, 首先建立一个element.id的副本, 再最后将element设置为null

function assignHandler() { var element = document.getElementById("someElement"); var id = element.id; element.onclick = function() { alert(id) }; element = null;}

关于this
var name = "the window"var object = { name: "my object", getName: function() { return this.name; }};object.getName();//"my object"(object.getName)();//"my object"(object.getName = object.getName)();//"the window"

模仿块级作用域
javaScript没有强类型语言中的块级作用域, 但可以利用匿名函数自执行来模拟;当一个函数声明被放在一个双扩里时, 就变成了表达式, 再添加双括号调用, 就会执行此函数;在函数内声明的变量, 也不会影响到外部, 实现块级作用域的效果.

(function() { for (var i = 0; i < 10; i++) { console.log(i); } })()console.log(i)//ERROR

私有变量
静态私有变量
JavaScript中的静态私有变量, 也是通过闭包模拟实现的;先用匿名函数自执行, 建立一个全新作用域, 这样变量就不能被外部直接访问,然后将构造函数挂载到外面的变量上暴露出去, 在其原型链上再添加获取和修改私有变量的方法,因为闭包的原因, 即使构造函数被实例化多次, 他们还是公用同一个name
值来实现静态效果.如果想通过原型对象上添加方法修改私有变量, 这样也无法实现, 因为在外面添加的原型方法,无法访问到里面作用域的变量.

var Person = null;(function() { var name = ""; Person = function(value) { name = value; } Person.prototype.setName = function(value) { name = value; } Person.prototype.getName = function() { return name; }})()var p1 = new Person("hello");p1.getName();//"hello"var p2 = new Person("world");p1.getName();//"world"p2.getName();//"world"Person.prototype.getName2 = function() { return name;}p1.getName2();//""

模块模式(单例模式)
var singleton = function() { //私有变量 var privateVar = 1; function privateFunc() { return privateVar; } //用户自定义的对象 var obj = new customObj(); //共有变量 obj.publicVar = true; //共有方法 obj.publicMethod = function() { privateVar ++; return privateFunc(); } return obj;}

相关文章

  • 前端闭包,私有变量,this,单例等。

    函数function funcName(arg0, arg1, arg2){}console.log(funcNa...

  • 模块模式

    模块模式 模块 模式实在单例对象上加上扩展,通过作用域链来关联私有变量和特权方法对象字面量封装模块,闭包实现私有和...

  • 2018-06-02 作用域链 闭包 匿名函数

    主要讲了闭包是什么 闭包造成的内存泄漏 匿名函数模拟私有变量 匿名函数模拟块级作用域 匿名函数模拟单例类 作用域链...

  • JS 闭包(Closure)

    JavaScript 变量可以是局部变量或全局变量。私有变量可以用到闭包。 简单点说闭包就是JS中用来实现私有变量...

  • javascript中闭包是什么

    javascript中闭包是什么 JavaScript 变量可以是局部变量或全局变量。私有变量可以用到闭包。闭包就...

  • js--闭包概念详解

    关于闭包,简而言之,每个函数都是一个闭包,闭包就是一个私有的空间。函数里面定义的变量和方法等都在这个私有空间中,外...

  • Swift的四种传值方法

    Swift中常用的四种传值方法:单例,单例,闭包(相当于OC的block传值),通知 1单例: 1>.创建单例变量...

  • (7)JavaScript单例模式

    概述 单例模式,顾名思义就是整个上下文中只存在一个实例。要实现这种模式,需要用到JavaScript闭包、私有变量...

  • 面试题 闭包 继承 原型

    闭包 什么是闭包?闭包的作用?闭包的应用?答: 函数执行,形成私有的执行上下文,使内部私有变量不受外界干扰,起到保...

  • JavaScript函数闭包

    JavaScript闭包 JavaScript 变量可以是局部变量或全局变量。私有变量可以用到闭包。 全局变量1....

网友评论

      本文标题:前端闭包,私有变量,this,单例等。

      本文链接:https://www.haomeiwen.com/subject/ewzmhxtx.html