精华内容
下载资源
问答
  • 闭包和作用域链

    2021-10-07 20:29:53
    1.理解 *就是一块“地盘”,一个代码段所在的区域 *他是静态的(相对于上下文对象),在编写... *全局作用域 *函数作用域 *没有块作用域(ES6有) 3.作用 *隔离变量,不同作用于下同名的变量不会有冲突

    闭包的理解:

             1.如何产生闭包

                *当一个嵌套的内部(子)函数引用了嵌套的外部(父)函数的变量(函数)时,就产生了闭包

             2.闭包到底是什么

                *理解一:闭包是嵌套的内部函数(绝大部分人)

                *理解二:包含被引用变量(函数)的对象(极少数人)

                *注意:闭包存在于嵌套的内部函数中

             3.闭包产生条件

                *函数嵌套

                *内部函数引用了外部函数的数据(变量/函数)

    <script type="text/javascript">
    		 function fn1(){
    			var a = 2;
    			function fn2(){//执行函数定义就会产生闭包(不用调用内部函数)
    				console.log(a)
    			}
    			fn2()
    		}
    	fn1()
    </script>

    常见的闭包

            <!-- 
    		 1.将函数作为另一个函数的返回值
    		 2.将函数作为实参传递给另一个函数调用
    		 -->
    		 <script type="text/javascript">
    			//将函数作为另一个函数的返回值
    		 	function fn1(){
    				var a = 2;
    				function fn2(){
    					a++
    					console.log(a)
    				}
    				return fn2;
    			}
    			var f = fn1()
    			f()
    			f()
    			//将函数作为实参传递给另一个函数调用
    			function showDelay(msg,time){
    				setTimeout(function(){
    					alert(msg)
    				},time)			
    			}
    			showDelay('哈哈哈',2000)
    		 </script>

    闭包的生命周期

            <!-- 
    		 产生:在嵌套内部函数定义执行完时就产生了(不是在调用)
    		 死亡:在嵌套的的内部函数成为垃圾对象时
    		 -->
    		<script type="text/javascript">
    			function fn1() {
    				//此时闭包就产生了(函数提升,内部函数对象已经创建)
    				var a = 2;
    				function fn2() {
    					a++
    					console.log(a)
    				}
    				return fn2;
    			}
    			var f = fn1()
    			f()
    			f()
    			f = null//闭包死亡(包含闭包的函数对象成为垃圾对象)
    		</script>

    什么是作用域

    1.理解
                *就是一块“地盘”,一个代码段所在的区域
                *他是静态的(相对于上下文对象),在编写代码时就确定了
    2.分类
                *全局作用域
                *函数作用域
                *没有块作用域(ES6有)
    3.作用
                *隔离变量,不同作用于下同名的变量不会有冲突

    作用域链的理解

            <!-- 
    		 1.理解
    			*多个上下级关系的作用域形成的链,它的方向是从下往上的
    			*查找变量是就沿着作用域链查找
    		 2.查找一个变量的查找规则
    			*在当前作用域下的执行上下文中查找对应的属性,如果有直接返回,否则进入2
    			*在上一级作用域的执行上下文中查找对应的属性,如果有直接返回,否则进入3
    			*再次执行2的相同操作,直到全局作用域,如果还找不到就抛出找不到的异常
    		 -->
    		<script type="text/javascript">
    			var a = 1
    			function fn1() {
    				var b = 2
    				function fn2() {
    					var c = 3
    					console.log(c)
    					console.log(b)
    					console.log(a)
    					console.log(d)
    				}
    				fn2()
    			}
    			fn1()
    		</script>

    展开全文
  • 理解闭包和作用域链

    2021-12-03 16:47:40
    闭包和作用域链 闭包:有权访问另一个函数作用域中变量的函数,可以突破作用。实现变量函数的无序访问。 作用域链:当访问一个变量时,解释器会首先在当前作用域查找标示符,如果没有找到,就去父作用域找,直到...

    闭包和作用域链

    闭包:有权访问另一个函数作用域中变量的函数,可以突破作用链。实现变量和函数的无序访问。
    作用域链:当访问一个变量时,解释器会首先在当前作用域查找标示符,如果没有找到,就去父作用域找,直到找到该变量的标示符或者不在父作用域中,这就是作用域链,由当前环境与上层环境的一系列变量对象组成,它保证了当前执行环境对符合访问权限的变量和函数的有序访问。

    Tipes: 利用闭包可以突破作用链,作用域链能合理的解释闭包的原理。

    闭包为什么会造成变量不被回收造成内存泄漏?
    首先我们都知道闭包是有权访问另外一个函数作用域变量的函数,这说明什么?就是闭包里面一直保持着对另外一个函数作用域内部变量的引用,那么变量回收是什么时候呐?当变量进入执行环境的时候,js垃圾回收机制会将其标记为“进入环境”,当变量离开环境的时候(函数执行结束)将其标记为“离开环境”,在离开环境之后还有的变量则是需要被删除的变量,从逻辑上讲,永远不能释放进入环境的变量。那么闭包一直保持着使用,那么这个变量还有变量所在的函数作用域都不会被回收,js运行内存就那么多,闭包数量多了,一来而去内存就泄漏了。

    为什么闭包能突破作用域链?
    我们要先知道突破是什么意思?当访问一个变量时,解释器会首先在当前作用域查找标示符,如果没有找到,就去父作用域找,直到找到该变量的标示符或者不在父作用域中,这就是作用域链,由当前环境与上层环境的一系列变量对象组成,它保证了当前执行环境对符合访问权限的变量和函数的有序访问。如果我们不想按照顺序来访问,我就想访问和我同级的函数内部的变量怎么办? 这时候闭包就发挥了它的作用了,因为闭包保持着对一个函数作用域的引用,那么这个函数作用域就一直不会被销毁,而且我们在哪里使用闭包都可以,只要闭包被创建了,这样不就突破了作用域链了吗?

    展开全文
  • 文章目录一、作用域全局作用域函数作用域块级作用域补充----动态作用域this(下一篇文章会继续介绍)二、变量的作用域全局变量局部变量全局变量局部变量的区别三、作用域链四、变量函数的声明提升变量的声明提升...

    一、作用域

    JavaScript的作用域是我们可以有效访问变量或函数的区域。JS具有三种类型的作用域:全局作用域、函数作用域和块级作用域(ES6)

    全局作用域

    全局空间中声明的变量或函数,我们可以在代码的任何位置访问到他们。

    全局作用域在页面打开时创建,页面关闭时销毁,在全局作用域中有一个全局对象window(代表的是一个浏览器的窗口,由浏览器创建),可以直接使用。

    • 所有创建的变量都会作为window对象的属性保存

    在这里插入图片描述

    • 所有创建的函数都会作为window对象的方法保存

    在这里插入图片描述

    函数作用域

    函数内部就是函数作用域,调用函数是创建函数作用域,函数执行完毕之后,函数作用域销毁。每调用一次函数就会创建一个新的函数作用域,它们之间是相互独立的。

    在函数内部声明的变量、函数和参数可以在该函数内部访问。函数外部是访问不到的。

    const fn = function myFunc() {
      var a = 66;
    }
    fn();
    console.log(a); //ReferenceError: a is not defined
    

    块级作用域

    被块{}包含的就是块级作用域。

    {}中声明的变量(let const)只能在会计作用域内访问

    if(true){
        let a = 1;
    };
    console.log(a); //ReferenceError: a is not defined
    

    补充----动态作用域this(下一篇文章会继续介绍)

    二、变量的作用域

    在JavaScript中,根据作用域的不同,变量可以分为两种:全局变量局部变量

    全局变量

    1、在全局作用域下声明的变量叫做 全局变量(在函数外部定义的变量)

    2、全局变量在全局(代码的任何位置)下都可以使用;全局作用域中无法访问到局部作用域中的变量。

    3、全局变量第一种创建方式:在全局作用域下 var声明的变量是全局变量

    4、全局变量第二种创建方式:如果在函数内部,没有使用 var关键字声明直接赋值的变量也属于 全局变量。(不建议使用)

    局部变量

    1、在局部作用域下声明的变量叫做局部变量(在函数内部定义的变量)

    2、局部变量只能在函数内部使用,在局部作用域中可以访问到全局变量。

    3、在函数内部 var 声明的变量就是局部变量

    4、函数的形参实际上就是局部变量

    全局变量和局部变量的区别

    全局变量:在任何一个地方都可以使用,全局变量只有在浏览器关闭的时候才会销毁,比较占用内存资源

    局部变量:只能在函数内部使用,当其所在代码块被执行时,会被初始化;当代码块执行完毕就会销毁,因此更节省节约内存空间;

    三、作用域链

    内部函数访问外部函数的变量,采取的是链式查找的方法来决定取那个结构,这种结构称之为作用域链

    作用域链的原则:就近原则

    (作用域链采用链式查找的方式,一层一层向上查找,先查找外面的嵌套的函数是否有所需内容,找到就输出相应的结果,如果没有再向上查找,直到查到全局作用域,这么一个查找过程形成的链条。)

    四、变量和函数的声明提升

    javascript是由浏览器解释执行的脚本语言,由浏览器js解释器进行解释执行,总的过程分为两个阶段,预编译阶段执行阶段

    在预编译阶段,js引擎就会读取变量的定义并确定其作用域即生效范围。

    变量提升的表现是,无论我们在函数中何处位置声明的变量,好像都被提升到了函数的首部,我们可以在变量声明前访问到而不会报错。

    造成变量声明提升的本质原因是 js 引擎在代码执行前有一个解析的过程,创建了执行上下文,初始化了一些代码执行时需要用到的对象。当我们访问一个变量时,我们会到当前执行上下文中的作用域链中去查找,而作用域链的首端指向的是当前执行上下文的变量对象,这个变量对象是执行上下文的一个属性,它包含了函数的形参、所有的函数和变量声明,这个对象的是在代码解析的时候创建的。这就是会出现变量声明提升的根本原因。

    变量的声明提升

    使用 var 关键字声明的变量,会在所有的代码执行之前被声明。(但是不会赋值)

    全局变量即使是写在最下面,也相当于在所有代码之前的最上面声明的变量。

    
    var name = 'Irene';
    
    function say(){
      console.log(name); //输出:undefined
      var name = 'Yovela';
      console.log(name); //输出:'Yovela'
    }
    
    say();
    

    解析:上述代码从结果看,say函数执行第一次打印name时,并未打印全局的name (Irene),而是打印局部的name(undefined),这是因为在预编译阶段,say函数内部进行了变量声明提升,提升后的执行效果如下:

    
    var name = 'Irene';
    
    function say(){
      var name; //变量name声明提升至作用域顶部,但未赋值,故为undefined
      console.log(name); //存在局部name,则无视全局name
      var name = 'Yovela'; //变量赋值保持原位
      console.log(name); //输出:'Yovela'
    }
    
    say();
    

    如果声明变量的时候不使用 var 关键字,那么变量就不会被声明提前。

    函数声明提升

    函数的两种创建方式:

    • 函数声明function () {}

    它会在所有代码执行之前就被创建。所以可以在函数声明之前被调用。

    say(); //输出:'saying'
    
    function say() {
      console.log('saying');
    }
    
    • 函数表达式var 变量名 = function 函数名() {}

    不会被声明提前,所以不能再声明前调用。

    say(); //报错:say is not a function
    
    var say = function () {
      console.log('saying');
    }
    

    解析:同样地先执行函数,后创建函数,结果却是不一样。原因在于,通过函数声明的方式,该函数声明(包括定义)会被提升至作用域的顶部,而表达式的创建方式则只提升了变量say至作用域的顶部,此时的say其值为undefined,调用say()自然报错“say is not a function”。

    var say = function () {
      console.log('1');
    };
    
    function say() {
      console.log('2');
    };
    
    say(); //输出:'1'
    

    解析:预编译阶段进行变量声明提升和函数声明提升后,上述代码执行效果等同于:

    var say; //变量声明提升
    
    function say() { //函数声明提升
      console.log('2');
    }
    
    say = function () { //变量赋值保持原位执行,say函数被覆盖
      console.log('1');
    };
    
    say(); //输出'1'
    

    变量声明和函数声明提升的联系

    1. 函数声明提升,会将函数的声明和定义全都提升至作用域顶部。变量声明提升,只提升声明部分(未赋值状态),赋值部分保持原位置不动。
    2. 同名情况下,函数声明提升优先级要高于变量声明提升,且提升后该函数声明定义不会被提升后的同名变量声明所覆盖,但是会被后续顺序执行的同名变量赋值所覆盖。

    五、原型

    原型对象理解

    • 函数对象的 prototype 属性

    我们创建的每一个函数都有一个 prototype 属性,这个属性是一个指针,指向一个对象。原型对象中的方法和属性都可以被函数的实例所共享。所谓的函数实例是指以函数作为构造函数创建的对象,这些对象实例都可以共享构造函数的原型的方法。

    这个对象的用途是包含可以由特定类型的所有实例共享的属性和方法,简单来说,该函数实例化的所有对象的__proto__的属性指向这个对象,它是该函数所有实例化对象的原型。

    function Person(){
    
    }
    
    // 为原型对象添加方法
    Person.prototype.sayName = function(){
        alert(this.name);
    }
    

    在这里插入图片描述

    • constructor 属性

    当函数创建,prototype 属性指向一个原型对象时,在默认情况下,这个原型对象将会获得一个 constructor 属性,这个属性是一个指针,指向 prototype 所在的函数对象。

    拿前面的一个例子来说 Person.prototype.constructor 就指向 Person 函数对象。

    在这里插入图片描述

    • 对象的 proto 属性

    当我们调用构造函数创建一个新实例后,在这个实例的内部将包含一个指针,指向构造函数的原型对象。

    
    var student = new Person();
    
    console.log(student.__proto__ === Person.prototype); // true
    

    从上面我们可以看出,这个连接是存在与实例与构造函数的原型对象之间的,而不是存在于实例和构造函数之间的。

    在这里插入图片描述

    原型属性

    • 属性访问

    每当代码读取对象的某个属性时,首先会在对象本身搜索这个属性,如果找到该属性就返回该属性的值,如果没有找到,则继续搜索该对象对应的原型对象,以此类推下去。

    • 属性判断

    在属性确认存在的情况下,我们可以使用 hasOwnProperty()方法来判断一个属性是存在与实例中,还是存在于原型中。注意这个方法只有在给定属性存在于实例中时,才会返回 true 。

    如果这个属性不一定存在的话,这样判断就不够准确,因此我们需要首先判断这个属性是否存在,然后再进行上面的判断操作。

    判断一个属性是否存在,我们可以使用in 操作符,它会在对象能够访问给定属性时返回 true,无论该属性存在于实例还是原型中。

    六、原型链

    ECMAScript 中描述了原型链的概念,并将原型链作为实现继承的主要方法。其基本思想是利用的一个引用类型继承另一个引用类型的属性和方法。

    原型链的主要实现方法是让构造函数的 prototype 对象等于另一个类型的实例,此时的 prototype 对象因为是实例,因此将包含一个指向另一个原型的指针(proto),相应地另一个原型中也包含着一个指向另一个构造函数的指针。假如另一个原型又是另一个类型的实例,那么上述关系依然成立,如此层层递进,就构成了实例与类型的链条。这就是原型链的基本概念

    不包含函数原型的以上实例所包含的原型链的关系图:

    在这里插入图片描述

    加入了函数原型后的原型链的关系图:

    在这里插入图片描述

    function Super() {};
    function Middle() {};
    function Sub() {};
    Middle.prototype = new Super();
    Sub.prototype = new Middle();
    var suber = new Sub();
    

    在这里插入图片描述

    七、闭包

    基本含义

    闭包是指有权访问另一个函数作用域中变量的函数,创建闭包的最常见的方式就是在一个函数内创建另一个函数,创建的函数可以访问当前函数的局部变量。

    比如:

    function outer()
    {    
        var a = 1;    
        function inner()
        {        
            console.log(a);    
        }    
        inner(); // 1}outer();
    }
    

    在 inner 函数中,我们可以通过作用域链访问到 a 变量,因此这就可以算是构成了一个闭包,因为 a 变量是其他函数作用域中的变量。

    特点

    • 让外部访问函数内部变量成为可能;
    • 能够读取函数内部的变量;
    • 局部变量会常驻在内存中;
    • 可以避免使用全局变量,防止全局变量污染;
    • 会造成内存泄漏(有一块内存空间被长期占用,而不被释放)

    应用场景

    • setTimeout 传参

    //原生的setTimeout传递的第一个函数不能带参数
    setTimeout(function(param) {
        alert(param)
    },1000);
    
    
    //通过闭包可以实现传参效果
    function myfunc(param) {
        return function() {
            alert(param)
        }
    };
    var f1 = myfunc(1);
    setTimeout(f1,1000);
    
    • 回调

    function say (value) {
        alert(value);
    }
    function execute (someFunction, value) {
        someFunction(value);
    }
    execute(say, 'hi js.');
    
    • IIFE(自执行函数)

      var arr = [];
        for (var i=0;i<3;i++){
          //使用IIFE
          (function (i) {
            arr[i] = function () {
              return i;
            };
          })(i);
        }
        console.log(arr[0]()) // 0
        console.log(arr[1]()) // 1
        console.log(arr[2]()) // 2
    
    • 函数防抖、节流

    比如绑定响应鼠标移动、窗口大小调整、滚屏等事件时,绑定的函数触发的频率会很频繁。若稍处理函数微复杂,需要较多的运算执行时间和资源,往往会出现延迟,甚至导致假死或者卡顿感。为了优化性能,这时就很有必要使用 debounce防抖throttle节流了。

    debounce与throttle区别

    防抖 (debounce) :多次触发,只在最后一次触发时,执行目标函数。

    节流(throttle):限制目标函数调用的频率,比如:1s内不能调用2次。

    // 函数防抖的实现
    function debounce(fn, wait) {
      var timer = null;
    
      return function() {
        var context = this,
          args = arguments;
    
        // 如果此时存在定时器的话,则取消之前的定时器重新记时
        if (timer) {
          clearTimeout(timer);
          timer = null;
        }
    
        // 设置定时器,使事件间隔指定事件后执行
        timer = setTimeout(() => {
          fn.apply(context, args);
        }, wait);
      };
    }
    

    在事件被触发 n 秒后再执行回调,如果在这 n 秒内事件又被触发,则重新计时。这可以使用在一些点击请求的事件上,避免因为用户的多次点击向后端发送多次请求。

    // 函数节流的实现;
    function throttle(fn, delay) {
      var preTime = Date.now();
    
      return function() {
        var context = this,
          args = arguments,
          nowTime = Date.now();
    
        // 如果两次时间间隔超过了指定时间,则执行函数。
        if (nowTime - preTime >= delay) {
          preTime = Date.now();
          return fn.apply(context, args);
        }
      };
    }
    
    

    规定一个单位时间,在这个单位时间内,只能有一次触发事件的回调函数执行,如果在同一个单位时间内某事件被触发多次,只有一次能生效。节流可以使用在 scroll 函数的事件监听上,通过事件节流来降低事件调用的频率。

    • 柯里化

    柯里化(Currying)是把接受多个参数的函数变换成接受一个单一参数(最初函数的第一个参数)的函数,并且返回接受余下的参数且返回结果的新函数的技术。

    var add = function(x) {
      return function(y) {
        return x + y;
      };
    };
    var increment = add(1);
    var addTen = add(10);
    increment(2);
    // 3
    addTen(2);
    // 12
    add(1)(2);
    // 3
    

    这里定义了一个 add 函数,它接受一个参数并返回一个新的函数。调用 add 之后,返回的函数就通过闭包的方式记住了 add 的第一个参数。所以说 bind 本身也是闭包的一种使用场景。

    柯里化是将 f(a,b,c) 可以被以 f(a)(b)(c) 的形式被调用的转化。JavaScript 实现版本通常保留函数被正常调用和在参数数量不够的情况下返回偏函数这两个特性。

    • 模块化

    模块化的目的在于将一个程序按照其功能做拆分,分成相互独立的模块,以便于每个模块只包含与其功能相关的内容,模块之间通过接口调用

    模块化开发和闭包息息相关,通过模块模式需要具备两个必要条件可以看出:

    • 外部必须是一个函数,且函数必须至少被调用一次(每次调用产生的闭包作为新的模块实例)
    • 外部函数内部至少有一个内部函数, 内部函数用于修改和访问各种内部私有成员
    function myModule (){
        const moduleName = '我的自定义模块'
        var name = 'sisterAn'
    
        // 在模块内定义方法(API)
        function getName(){
            console.log(name)
        }
        function modifyName(newName){
            name = newName
        }
    
        // 模块暴露:  向外暴露API
        return {
            getName,
            modifyName
        }
    }
    
    // 测试
    const md = myModule()
    md.getName()    // 'sisterAn'
    md.modifyName('PZ')
    md.getName()    // 'PZ'
    
    // 模块实例之间互不影响
    const md2 = myModule()
    md2.sayHello = function () {
        console.log('hello')
    }
    console.log(md) // {getName: ƒ, modifyName: ƒ}
    

    解决闭包带来的问题

    1. 使用块级声明变量—let const
    2. 使用IIFE
    3. 使用foreach进行循环
    展开全文
  • 3.什么是作用域链 [[scope]]:每个javascript函数都是一个对象,对象中有些属性我们可以访问,但有些不可以,这些属性仅供javascript引擎存取,[[scope]]就是其中一个。[[scope]]指的就是我们所说的作用域,其中存储了...

    1.闭包是什么 闭包的优点和缺点是什么
    函数return返回一个函数
    优点:函数外部可以调用函数内部变量;变量不会被污染
    缺点:会导致内存泄漏

    2.什么是作用域
    变量的执行环境

    3.什么是作用域链
    [[scope]]:每个javascript函数都是一个对象,对象中有些属性我们可以访问,但有些不可以,这些属性仅供javascript引擎存取,[[scope]]就是其中一个。[[scope]]指的就是我们所说的作用域,其中存储了运行期上下文的集合。即作用域决定了代码区块中变量和其他资源的可见性,作用域与作用域之间通过 scope 连接从而形成了作用域链
    scope 是一个数组存所有存放所有使用的变量

    4.如何解决闭包导致内存泄露
    可以利用垃圾回收机制中标记清除法;
    1再满足条件收;将引用函数的变量 赋值为 null 做到零引用
    立即执行函数;因为立即执行函数为零引用

    5.从作用域的角度 说一下 为什么闭包中外部可以访问内部的函数变量
    因为外部接收了函数reutrn 返回的函数 实际上变量存的是函数的指针;return 返回的函数是 函数的子作用域;作用域之间可以通过scope 连接;从而子作用域中可以访问父作用域中的变量。return返回的函数是再函数外部调用,
    所以 外部可以访问内部

    6.垃圾回收机制的认识
    没有被引用的对象 数组 或者函数;会被垃圾回收机制 回收;释放空间;

    7.从内存角度谈谈你对闭包的认识
    因为 闭包中返回的函数 被全局变量所引用;所以导致 函数中变量不会释放,内存泄露;
    可以通过;标记清除发;以及立即执行函数方式 解决这个问题

    8.如何将一个类数组变为真数组?请写出 2中方法
    1: 结构赋值 …
    2: Array.from()
    3: for循环遍历

    9.什么是递归呢?递归的弊端但是什么?
    递归:函数内部 自己调用自己
    不断:最先执行的最后输出;需要找出出口 会导致性能差

    10.作用域是什么时候产生的呢?
    全局:window对象创建时候
    局部:函数执行时候;执行期上下文对象创建时候

    11.请说出你判断this 指向的方法是什么呢?
    1: 先看 this 在哪个做作用域中?
    全局—> this = window
    箭头函数—> 看上一层作用域中中this
    function 函数体中。
    2:看函数执行。
    2.0: 判断哪一个函数被执行?再看方法体中 this 指向谁?
    2.1 看是否有call apply bind ,有—> 参一是谁 this 就指向谁
    2.2 看是否是事件处理函数; 是----> 触发事件元素
    2.3 调用函数是否是new 是构造函数,this 指向new 实例的对象
    2.4 以上都不满足。谁调用指向谁。

    12.谈谈你对原型 原型链 继承的认识
    原型:JS在创建对象(不论是普通对象还是函数对象)的时候,都有一个叫做__proto__的内置属性,用于指向创建它的函数对象的原型对象prototype 。 每个对象都有原型对象;null 除外
    原型链:有__proto__串起来的直到Object.prototype.__proto__为null的链叫做原型链。
    继承,原型对象中属性是通过原型链继承的;对象可以执行访问继承的所有的原型对象中的属性。

    13.Function与 function的区别是什么
    Function 是 functiohn 的构造函数 都是函数对象
    function 的 原型对象为 普通对象
    Function 的原型对象为 函数对象;但是 这个函数对象没有原型对象了

    14.什么是异步?
    异步:执行慢额程序 放在异步中。
    异步:非阻塞代码执行。当满足执行条件后;才执行这个代码

    15.什么是回掉函数
    回掉函数:将一个函数作为参数传入到另一个函数中。那么即是callback

    16.请说一下你是如何理解 js 是解析型语言的
    语言分析
    预编译 GO AO
    解析执行

    17.执行期上下文
    函数执行时,会创建一个称为执行期上下文的内部对象,一个执行期上下文定义了一个函数执行时的环境,函数每次执行时对应的执行上下文都是独一无二的,所以多次调用一个函数会导致创建多个执行上下文,当函数执行完毕,执行上下文被销毁。

    18.call apply bind 的区别
    相同点:都会改变 触发的function 函数;函数体中 this 执向
    bind() 需要执行符触发函数 .bind()()
    apply() 两个参数;参二 为数组;给触发函数传入实参
    call() n个参数 参二以后都是给触发函数传入实参

    19.变量的使用规则
    先再自己的作用域中找看是否有 var 或者其他方式声明这个变量 如果没有 往祖籍域中找。直到找到距离最近的 声明的变量;并使用最近的一次赋值。
     

    展开全文
  • 引言在JavaScript中有作用域作用域链和闭包。我们最开始可能觉得知道这些的定义就算懂了(刚入门时的我也是这样),但是当深入了解的时候,发现自己知道的只是皮毛。所以,这篇文章将详细讲解作用域作用域链和闭包...
  • 解读一下这张图,让我想起了在庆余年里追司理理的时候,王启年给小范大人解读那张他画的鬼斧神工的地图。乍一看,还有点像哥斯拉...根据作用域链,内部函数总是可以访问其所在的外部函数中声明的参数变量 闭包...
  • 函数作用域和闭包

    2021-01-14 20:47:51
    闭包可以更新外部变量的值作用域链全局环境非嵌套的函数嵌套的函数多个闭包 闭包   引用红皮书 p178 上对闭包的陈述: 闭包是指有权访问另一个函数作用域中的变量的函数。   有两个要点: 闭包是函数 它可以...
  • 前言:JavaScript深入理解scope作用域和闭包,就要先理解什么是执行上下文和执行栈。作用域、作用域闭包是JavaScript的难点也是重点,其实理解起来也不难,学习过其他语言,比如C语言就可以很好的类比。 一 知识...
  • 闭包和作用域

    2021-04-24 21:06:30
    通俗的得讲就是函数 a的内部函数b,被函数a外部的一个变量引用的时候,就创建了一个闭包。在函数封装,使用定时器的时候用到。 例一 : function a(){ var i=0; function b(){ alert(++i); } return b; } var ...
  • 《js高级程序设计》红宝书上对于闭包的定义:闭包是指有权访问另外一个函数作用域中的变量的函数。 MDN 对闭包的定义为:闭包是指那些能够访问自由变量的函数。这里的自由变量是外部函数作用域中的变量。 概述上面...
  • GO:globalobject 即 全局上下文 AO :activationobject活跃对象,函数上下文, 在函数执行之前进行的一个步骤 jS代码编译过程: ...1.寻找函数的形参变量声明 2.把实参的值赋值给形参 3.寻找函数声明,...
  • 在js中,作用域分为全局作用域、函数作用域、块级作用域作用域 作用域就是一个变量在代码运行时可被访问的范围。作用域最大的用处就是隔离变量,不同作用域下同名变量不会有冲突。 全局作用域 <script> ...
  • 将从是什么、作用、实际工作的应用三个维度去诠释闭包作用域链、内存泄漏
  • 面试之闭包作用域

    2021-03-10 23:12:52
    实际上,闭包其实就是缓存作用域,使函数外部打破函数作用域的约束。可以访问函数内部的变量。同样,他的副作用就是销毁内存。 使用场景: ajax中的回调函数,setTimeout中的匿名函数。或者一个函数返回函数,其实...
  • 什么是闭包在维基中,闭包的...所以,有另一种说法认为闭包是由函数与其相关的引用环境组合而成的实体。闭包在运行时可以有多个实例,不同的引用环境相同的函数组合可以产生不同的实例。我们来看一个简单的实...
  • 一、作用域 1、js中作用域: 全局作用域、函数作用域、块级作用域(es6增加) ...1.1、作用域链 vs 执行上下文 js解释型语言,执行分为:解释、执行两个阶段。分别处理事情不一样: 解释阶段: 词法
  • 作用域链闭包

    2021-04-05 17:53:20
    在了解了JS执行和作用域之后,我们来讲讲作用域链 注:个人理解。 什么是作用域链? 我认为,在内部函数访问外部变量时,所产生的链式查找方式就是作用域链。 举个栗子 var a = 10; function fn() { function foo()...
  • 闭包是什么? function createComp(){ let str = " 我是一个值" ...当createComp被调用时,会创建一个执行环境,以及相应的作用域链。并把作用域链赋值给一个内部属性[[scope]]。 然后使用this, argument
  • 关于Python作用域的知识在python作用...而这个被内部函数引用的变量则被成为自由变量闭包和函数调用没多少相关,而是关于使用定义在其他作用域的变量命名空间和作用域我们把命名空间看做一个大型的字典类型(Dict),...
  • 闭包和作用域的理解

    2021-05-14 08:10:52
    闭包: 全局环境不会被回收(有需要就不会被回收) 函数作用域中(函套函),小函数可访问父级函数的变量(前提是函数嵌套函数) 函数创建调用之后,就会创建一块新的天地
  • 一:变量作用域变量可以是局部域或者全局域。定义在函数内的变量有局部作用域,在一个模块中最高级别的变量有全局作用域。全局变量的一个特征是除非被删除掉,否则它们的存活到脚本运行结束,且对于所有的函数,他们...
  • 作用域可以根据代码层次分层,子作用域可以访问到父作用域,通常是通过链式的作用域链查找。而父作用域是引用不到子作用域里的变量引用。 闭包 一个函数对其周围状态的引用捆绑,这个组合就是闭包(或者说被引用...
  • 作用域指的是一个变量和函数的作用范围,在ES6中,只有全局作用域和局部作用域,但是没有块级作用域,并且局部变量的优先级高于全局变量。 1.变量提升 这里涉及一个知识点就是允许var在变量声明前使用,不会像let、...
  • 学到装饰器,然后总结一下理解装饰器需要的知识一.python的作用域当然,Python与大多数编程语言一样,搜索变量值的时候,即命名空间的规则,会采用'就近原则'.具体来说,由近及远依次为: 本地作用域(Local) --> ...
  • 对于许多新手来说,作用域的概念并不是很容易理解,我会尽量用最简单的方式来解释作用域和作用域。 JS的作用域 1、什么是作用域 作用域是在运行时代码中的某些特定部分中变量,函数和对象的可访问性。换句话说...
  • JS中有两种作用域类型 作用域类型:局部作用域、全局作用域。 局部作用域:在局部内定义的变量,从外部是不可见的。 <...全局作用域:网页的所有脚本函数都能访问它。 ①全局变量 <scr
  • 作用域闭包作用域链词法作用域块级作用域中的变量查找闭包闭包是怎么回收的总结 理解作用域是理解闭包的基础,而闭包在 JavaScript 中几乎无处不在,同时作用域和作用域还是所有编程语言的基础。所以,如果...
  • 编译原理 var a = 2 1、var a 没有a:编译器就会在当前作用域新建 有a:当前作用域就会让编译器忽略 ...引擎到作用域里找a,有两种方式: LHS 查询 RHS 查询。 当变量出现在赋值操作的左侧时进行
  • 闭包 闭包 函数内部返回一个新的函数 1.函数作为另一个函数的返回值 var a = 200; function fn1(){//0x0001 var a = 1; return function (){//0x0002 console.log(a);//1 } } var fn = fn1(); //0x0002 fn();//–>...
  • 该系列一共分为上、中、下三册,本读后感为上系列,着重介绍了两部分:作用域和闭包、this和原型对象。 作用域 理解作用域,首先需要理解程序的运行过程中的几个重要角色 引擎 从头到尾负责整个JavaScript程序的...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 78,809
精华内容 31,523
关键字:

闭包和作用域链