美文网首页
js闭包及作用域/作用域链

js闭包及作用域/作用域链

作者: 小麻烦爱学习 | 来源:发表于2020-01-16 11:10 被阅读0次

闭包的基础是作用域即作用域链

作用域

作用域是指程序源代码中定义这个变量的区域.全局变量拥有全局作用域,在程序中始终是有定义的.局部变量有局部作用域,在函数体内及所嵌套的函数内是有定义的.函数的参数是局部变量,它的作用域在函数体内

作用域链

作用域链是一个对象列表或者链表,这组对象定义了一段码的作用域中的变量.
当javascript查找一个变量x的值时,从链表的第一个对象开始查找,如果这个对象有x属性,那么返回这个属性的值,如果第一个对象不存在x属性,接着在第二个对象查找x属性.以此类推,直到全局作用域.如果作用域链式没有任何一个对象有x属性,那么,抛出引用错误(ReferenceError)异常

闭包

一个函数通过作用域链能够读取其他函数的变量,这种特性叫做闭包


和大多数现代编程语言一样,js页采用词法作用域: 函数的执行依赖变量作用域,这个作用域是在函数定义时决定的,而不是函数调用的时候.
函数对象的内部状态不仅包含代码逻辑,还必须引用当前的作用域链.

var scope = "global scope"
function checkscope () {
    var scope = "local scope"
    function f() {
        return scope;
    }
    return f();
}
checkscope() // =>"local scope",结果是显然的

对代码做一点改动:

var scope = "global scope"
function checkscope () {
    var scope = "local scope"
    function f() {
        return scope;
    }
    return f;
}
checkscope()() // =>"local scope",结果有点意外

函数定义时的作用域链在函数执行时依然有效

function counter () {
    var n = 0;
    return {
        count: function(){
            return n++;
        },
        reset: function(){
            return n = 0;
        }
    }
}
var a = new counter(); //创建了两个独立的作用域链和私有变量
var b = new counter();
console.log(a.count());// =>0
console.log(b.count());// =>0
console.log(a.reset());// =>0
console.log(b.count());// =>1

应用场景
  1. 实现对象的私有属性存取器
function defineProperty(o, property){
    var value = '';
    o['set' + property] = function (v) {
    value = v;
    }
    o['get' + property] = function (v) {
    return value;
    }
}
var obj = {};
defineProperty(obj,'Name')
obj.setName('javascript');
console.log(obj.getName());
  1. 防抖函数(n秒内只执行一次,如果n秒被再次触发,那么重新计时),把
function debounce (fn, ms) {
let timer = null;
return function (... args) {
    if(timer){
        clearTimeout(timer);
    }
    timer = setTimeout(fn.applay(this, args), ms)
}
}
  1. 模拟块级作用域(for循环)

  2. 缓存执行结果
    var fn=(function(){
    var cache={}//将结果缓存到该对象中,
    return function(){
    var str=JSON.stringify(arguments);
    if(cache[str]){//
    return cache[str];
    }else{//进行计算并返回结果
    var sum=0;
    for(var i=0;i<arguments.length;i++){
    sum+=arguments[i];
    }
    return cache[str]=sum;
    }
    }
    })()

  3. 柯里化函数式编程
    // 柯里化之前
    function add(x, y) {
    return x + y;
    }
    add(1, 2) // 3

    // 柯里化之后
    function addX(y) {
    return function (x) {
    return x + y;
    };
    }
    addX(2)(1) // 3
    6.单例模式


练习题目:

 function fun(n,o){
    console.log(o);
    return {
        fun:function(m){
            return fun(m,n);
        }
    };
 }

 var a = fun(0);a.fun(1);a.fun(2);a.fun(3);
 var b = fun(0).fun(1).fun(2).fun(3);
 var c = fun(0).fun(1);c.fun(2);c.fun(3);

相关文章

  • JavaScript 作用域链及闭包

    作用域链及闭包

  • js 总结七07-19

    作用域 全局 局部 作用域链 闭包

  • JavaScript 函数闭包(colsure)

    理解闭包,你首先必须理解JS的变量作用域,JavaScript作用域和作用域链。 ES6之前,变量的作用域分为全局...

  • 2023-01-12

    变量提升调用栈块级作用域作用域链和闭包 闭包 => 作用域链(词法作用域) => 调用栈(栈溢出) => 上下文...

  • JS博客

    JS构造函数及new运算符 JS原型对象和原型链 函数作用域和作用域链 干货分享:让你分分钟学会JS闭包 深入理解...

  • js作用域、闭包

    闭包 闭包作用 全局 局部 作用域链

  • 闭包

    一、理解闭包前js基础1、作用域链(作用域、作用域链中有说)。2、js的内存回收机制。一个函数在执行开始的时候,会...

  • 执行上下文,词法作用域,作用域链,闭包

    执行上下文,词法作用域,作用域链,闭包

  • 《Web前端开发之JavaScript精英课堂》(六)

    对 作用域、作用域链、执行上下文对象(GO | AO)、闭包 的个人理解: JS分为全局和局部作用域,都属于词法作...

  • js 闭包

    一、js 作用域 讲闭包首先就要理解 js 的作用域。再 ES5 中,js 有两种作用域,全局作用域和函数作用域(...

网友评论

      本文标题:js闭包及作用域/作用域链

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