JS作用域链和闭包实例分享
执行上下文可以理解为当前代码的执行环境,它会形成一个作用域。
- 范围:一段< script >或者一个函数
- 全局:变量定义,函数声明 (在一段< script >里)
- 函数:变量定义,函数声明,this,arguments
console.log(a);var a = a; fn('dong');function(){}
这段代码中现将var a与函数fn()提出来放在执行代码之前
++this++
var a = { name:'A', fn:function(){ console.log(this.name) } } a.fn();//this === A a.fn.call({name:'B'})//this === {name :'B'}var fn1 = a.fn; fn1(); //this==windowfn1;
this要在执行时才能确认值,定义时无法确认.
作为构造函数执行
function Foo(name){ this.name = name; }var f = new ('dong');
作为对象属性执行
var obj = { name :'a', printName:function(){ console.log(this.name); } } obj.printName(); //a
作为普通函数执行
function fn(){ console.log(this);//this===window}
call apply bind
//callfunction fn1(name,age){ alert(name,age); console.log(this); } fn1.call({x:100},'dong',200);//弹出dong 200//打印{x:100}//call将this指向第一个参数的值//常用它来改变函数的this值//apply与call类似//bindfunction fn1(name,age){ alert(name); console.log(this); } fn.call({x:100},'dong',20);//this为{x:100}var fn2 =function (name,age){ alert(name); console.log(this); }.bind({y:200});//必须用函数表达式的方式fn2.call('dong',20); //this为{y:200}
++作用域++
//无块级作用域if(true){ var name = 'dong'; } console.log(name);//函数和全局作用域var a =100; function fn(){ var a =200; console.log('fn',a); } console.log('global',a);fn();
++作用域链++
一个自由变量,一直不断地往父级作用域上找,形成的一个链式结构,就叫作用域链。
var a = 100;function(){ var b = 200; console.log(a);//当前作用域中没有定义a,a就是自由变量 console.log(b); }
var a = 100;function F1(){ var b =200; function F2(){ var c = 300; console.log(a); console.log(b); console.log(c); } }
++闭包++
函数作为返回值
函数作为参数来传递
function F1(){ var a = 100; return function(){ console.log(a); } }var f1 = F1();//表示变量f1是一个函数var a = 200; f1(); //100//全局里的a与在F1作用域里的a是没有关系的,一个函数的父级作用域是它定义时候的作用域而不是它执行的作用域,所以a这个自由变量直接在它的父级作用域中直接找到。
function F1(){ var a = 100; return function(){ console.log(a); } }var f1 = F1();function F2(fn){ var a = 200; fn(); } F2(f1);//100
相关题目
对变量提升的理解
说明this几种不同的使用场地
作为构造函数执行;作为对象属性执行;作为普通对象执行;call apply bind (具体代码见上部分)
- 创建10个< a >标签,点击的时候出来对应的序号
//考察作用域var i,a;for(var i = 0;i<10;i++){ a = document.creatElement('a'); a.innerHTML = i +<br/>; a.addEventListener('click',function(e){ e.preventDefault(); alert(i); //自由变量需要从父级作用域获取值 }) document.body.appendChild(a); }//这时候监听事件里的函数的自由变量,已经变为10了,所以,不管点击哪个它的序号都是10
//正确方法var i;for (i = 0;i < 10;i++){ (function(i){ var a = document.creatElement('a'); a.addEventListener('click',function(e){ e.preventDefault(); alert(i); }) document.body.appendChild(a); })(i);//自调用函数立即执行}//(function(i){})(i)//自执行函数,就是不用调用,只要定义完成就能立即执行的函数
理解作用域
自由变量;作用域链,即自由变量的查找;闭包的两个场景。
实际开发中闭包的应用(作用域的实际应用)
//主要作用用于封装变量,收敛权限funciton isFirstLoad(){ var _list = []; return function(id){ if(_list.indexOf(id) >= 0){ return false; }else{ _list.push(id); return true; } } }//使用var firstLoad = idFirstLoad(); firstLoad(10); //truefirstLoad(10); //falsefirstLoad(20); //true//在isFirstLoad函数外面,根本不可能修改掉__ list的值
相关推荐:
以上是JS作用域链和闭包实例分享的详细内容。更多信息请关注PHP中文网其他相关文章!

热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

AI Hentai Generator
免费生成ai无尽的。

热门文章

热工具

记事本++7.3.1
好用且免费的代码编辑器

SublimeText3汉化版
中文版,非常好用

禅工作室 13.0.1
功能强大的PHP集成开发环境

Dreamweaver CS6
视觉化网页开发工具

SublimeText3 Mac版
神级代码编辑软件(SublimeText3)

热门话题

typedef struct 在 C 语言中用于创建结构体类型别名,简化结构体使用。它通过指定结构体别名将一个新的数据类型作为现有结构体的别名。优点包括增强可读性、代码重用和类型检查。注意:在使用别名前必须定义结构体,别名在程序中必须唯一并且仅在其声明的作用域内有效。

Java 中的变量期望值异常可以通过以下方法解决:初始化变量;使用默认值;使用 null 值;使用检查和赋值;了解局部变量的作用域。

JavaScript 闭包的优点包括保持变量作用域、实现模块化代码、延迟执行和事件处理;缺点包括内存泄漏、增加了复杂性、性能开销和作用域链影响。

C++ 中的 #include 预处理器指令将外部源文件的内容插入到当前源文件中,以复制其内容到当前源文件的相应位置。主要用于包含头文件,这些头文件包含代码中需要的声明,例如 #include <iostream> 是包含标准输入/输出函数。

C++智能指针的生命周期:创建:分配内存时创建智能指针。所有权转移:通过移动操作转移所有权。释放:智能指针离开作用域或被明确释放时释放内存。对象销毁:所指向对象被销毁时,智能指针成为无效指针。

可以。C++ 允许函数嵌套定义和调用。外部函数可定义内置函数,内部函数可在作用域内直接调用。嵌套函数增强了封装性、可复用性和作用域控制。但内部函数无法直接访问外部函数的局部变量,且返回值类型需与外部函数声明一致,内部函数不能自递归。

JavaScript 中,this 的指向类型有:1. 全局对象;2. 函数调用;3. 构造函数调用;4. 事件处理程序;5. 箭头函数(继承外层 this)。此外,可以使用 bind()、call() 和 apply() 方法显式设置 this 的指向。

在 Vue 中,let 和 var 声明变量时在作用域上存在差异:作用域:var 具有全局作用域,let 具有块级作用域。块级作用域:var 不创建块级作用域,let 创建块级作用域。重新声明:var 允许在同一作用域内重新声明变量,let 不允许。
