JavaScript闭包和范围实例详解

本文实例分析了JavaScript闭包和范围。分享给大家供大家参考,具体如下:

1.

if (!("a" in window)) {
  var a = 1;
}
alert(a);

【分析】代码含义:如果window不包含属性a,就声明一个变量a并赋值为1

①JS引擎会先扫描所有的变量声明

②所有的全局变量都是window的属性

③变量声明和赋值一起用时,Js引擎会自动将它分成两部分:变量声明提前,变量赋值没有(不将赋值提前是因为他有可能影响代码执行出不可预期的结果)

所以代码执行顺序等价于

var a;
if(!("a" in window)) {
  a = 1;
}
alert(a);

解析:声明变量a,判断a是否存在,不存在就赋值为1,而这里a永远在window里存在,赋值语句永不执行,所以结果是undefined

2.

if (!("a" in window)) {
  function a() { window.a = 1; }
}
alert(a);

【分析】

①函数声明也会提前并且会覆盖变量声明,但不会覆盖变量赋值,如下例子

function value(){
  return 1;
}
var value;
alert(typeof value);  //"function"
function value(){
  return 1;
}
var value = 1;
alert(typeof value);  //"number"

②所有全局变量都是window属性,语句var a=1;等同于window.a=1;

所以代码执行顺序等价于

function a() {window.a = 1;}
if(!("a" in window)) {
  function a() { var a = 1; }
}
alert(a);

输出结果:function a() {window.a = 1; }

变形:

if ("a" in window) {
  function a() { window.a = 1; }
}
alert(a);

输出结果:a is not defined

函数声明里的变量定义,要到执行函数时才会定义,并不会在预编译阶段就声明变量

3.

if (!("a" in window)) {
  var a = function () { window.a = 1; }
}
alert(a);

【分析】

①函数声明和函数表达式区别

函数声明:

function functionName(arg1, arg2){
  //函数体
}

函数表达式(相当于变量赋值):

var functionName = function(arg1, arg2){
  //函数体
};

所以代码执行顺序等价于

var a;
if (!("a" in window)) {
  a = function () { window.a = 1; }
}
alert(a);

结果和第一题一样,undefined

4.

var a = 1,
  b = function a(x) {
    x && a(--x);
  };
alert(a);

【分析】

①进入执行上下文的阶段

VO(global) = {
  a: undefined,
  b: undefined
}

这阶段的顺序:函数的形参->函数声明->变量声明

②执行代码阶段

VO(global) = {
  x: undefined,
  a: 1
}

③定义变量b,赋值名字为a的函数(这个a只能在函数体内使用)

④如果x是任何true值(这这里应该是非0)则执行后面的语句

⑤换成更能理解的代码

var a = 1,
  b = function(x) {
    x && b(--x);
  };
alert(a);

结果为1

5.

function b(x, y, a) {
  arguments[2] = 10;
  alert(a);
}
b(1, 2, 3);

【分析】没有难点,输出10,如果改成

function b(x, y, a) {
  arguments[2] = 10;
  alert(a);
}
b(1, 2);

则输出undefined,因为没有传递a的值

6.

function a() {
  alert(this);
}
a.call(null);

【分析】

①a.call(b)表示a对象的方法应用到b对象上(即b对象继承了a对象),根据规定,第一个参数是null或undefined,call方法就把全局对象(也就是window)作为this的值

②call()和apply()的区别:功能一样,第二个参数形式不一样,call传递多个参数,任意形式,apply第二个参数必须是数组形式,如

a.call(b,2,3); ==>  a.apply(b,[2,3]);

输出结果:[object Window]

更多关于JavaScript相关内容可查看本站专题:《javascript面向对象入门教程》、《JavaScript中json操作技巧总结》、《JavaScript切换特效与技巧总结》、《JavaScript查找算法技巧总结》、《JavaScript错误与调试技巧总结》、《JavaScript数据结构与算法技巧总结》、《JavaScript遍历算法与技巧总结》及《JavaScript数学运算用法总结》

希望本文所述对大家JavaScript程序设计有所帮助。

(0)

相关推荐

  • 详解JavaScript的闭包、IIFE、apply、函数与对象

    目录 一.闭包(Closure) 1.1.闭包相关的问题 1.2.理解闭包 二.对象 2.1.对象常量(字面量) 2.2.取值 2.3.枚举(遍历) 2.4.更新与添加 2.5.对象的原型 2.6.删除 2.7.封装 三.函数 3.1.参数对象 (arguments) 3.2.构造函数 3.3.函数调用 3.3.1.call 3.3.2.apply 3.3.3.caller 3.3.4.Callee 3.5.立即执行函数表达式 (IIFE) 3.5.1.匿名函数与匿名对象 3.5.2.函数与函数

  • 通俗易懂地解释JS中的闭包

    1. "闭包就是跨作用域访问变量." [示例一] var name = 'wangxi' function user () { // var name = 'wangxi' function getName () { console.log(name) } getName() } user() // wangxi 在 getName 函数中获取 name,首先在 getName 函数的作用域中查找 name,未找到,进而在 user 函数的作用域中查找,同样未找到,继续向上回溯,发现在

  • js闭包用法实例详解

    本文实例讲述了js闭包用法.分享给大家供大家参考,具体如下: 引言 在公司中需要写一个js脚本来进行网站的统计,实现类似百度统计或者站长统计的功能,在实现的过程中自己感觉写的代码还是可以的,因为之前的js代码都是这些写,但是在组长代码走查的时候却非常的不满意,因为我们在js中写的方法都是全局的方法,因为我们写的东西需要嵌入到别人的界面中,所以这些全局的东西很可能会和别人的东西重名从而引发错误,所以说组长就给我留下一句话:用js闭包包起来. 变量作用域 我们都非常的熟悉变量的作用域就分为:全局变量

  • 深入理解javascript函数参数与闭包

    最近在学习javascript的函数,函数是javascript的一等对象,想要学好javascript,就必须深刻理解函数.本人把学习的过程整理成文章,一是为了加深自己函数的理解,二是给读者提供学习的途径,避免走弯路.内容有些多,但都是笔者对于函数的总结. 1.函数参数 1.1:参数是什么 1.2:参数的省略 1.3:参数默认值 1.4:参数传递方式 1.5:同名参数 1.6:arguments对象 2.闭包 2.1:闭包定义 2.2:立即调用的函数表达式(IIFE, Immediately

  • 浅谈JavaScript for循环 闭包

    有个网友问了个问题,如下的html,为什么每次输出都是5,而不是点击每个p,就alert出对应的1,2,3,4,5. <html > <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>闭包演示</title> <script type="text/javascript&quo

  • JavaScript中闭包的写法和作用详解

    1.什么是闭包 闭包是有权访问另一个函数作用域的变量的函数. 简单的说,Javascript允许使用内部函数---即函数定义和函数表达式位于另一个函数的函数体内.而且,这些内部函数可以访问它们所在的外部函数中声明的所有局部变量.参数和声明的其他内部函数.当其中一个这样的内部函数在包含它们的外部函数之外被调用时,就会形成闭包. 2.变量的作用域 要理解闭包,首先要理解变量的作用域. 变量的作用域无非就是两种:全局变量和局部变量. Javascript语言的特殊之处,就在于函数内部可以直接读取全局变

  • Javascript闭包与函数柯里化浅析

    闭包和柯里化都是JavaScript经常用到而且比较高级的技巧,所有的函数式编程语言都支持这两个概念,因此,我们想要充分发挥出JavaScript中的函数式编程特征,就需要深入的了解这两个概念,闭包事实上更是柯里化所不可缺少的基础. 一.柯里化的概念 在计算机科学中,柯里化是把接受多个参数的函数变换成接受一个单一参数(最初函数的第一个参数)的函数,并且返回接受余下的参数且返回结果的新函数的技术.这个技术由Christopher Strachey以逻辑学家 Haskell Curry 命名的,尽管

  • JS 循环li添加点击事件 (闭包的应用)

    废话不多说了,直接给大家贴代码了,具体代码如下所述: var aLi = document.querySelectorAll('.article-tab li'); for (var i = 0; i <= aLi.length; i++) { (function(){ var p = i aLi[i].onclick = function() { alert(p); } })(); } 以上所述是小编给大家介绍的JS 循环li添加点击事件 (闭包的应用),希望对大家有所帮助,如果大家有任何疑问

  • JavaScript闭包实例详解

    一.充电 1.一切(引用类型)都是对象,对象是属性的集合. 2.函数是一种对象,但是函数却不像数组一样--你可以说数组是对象的一种,因为数组就像是对象的一个子集一样.但是函数与对象之间,却不仅仅是一种包含和被包含的关系,函数和对象之间的关系比较复杂,甚至有一点鸡生蛋蛋生鸡的逻辑. function Fn() {this.name = '王福朋';this.year = 1988;} var fn1 = new Fn(); var obj = { a: 10, b: 20 };等价于var obj

  • JavaScript闭包和范围实例详解

    本文实例分析了JavaScript闭包和范围.分享给大家供大家参考,具体如下: 1. if (!("a" in window)) { var a = 1; } alert(a); [分析]代码含义:如果window不包含属性a,就声明一个变量a并赋值为1 ①JS引擎会先扫描所有的变量声明 ②所有的全局变量都是window的属性 ③变量声明和赋值一起用时,Js引擎会自动将它分成两部分:变量声明提前,变量赋值没有(不将赋值提前是因为他有可能影响代码执行出不可预期的结果) 所以代码执行顺序等

  • javascript 中的继承实例详解

    javascript 中的继承实例详解 阅读目录 原型链继承 借用构造函数 组合继承 寄生组合式继承 后记 继承有两种方式:接口继承和实现继承.接口继承只继承方法签名,而实现继承则继承实际的方法. 由于函数没有签名,在ECMAScript中无法实现接口继承.ECMAScript只支持实现继承,而且实现继承主要依靠原型链来实现. 下面介绍几种js的继承: 原型链继承 原型链继承实现的本质是重写原型对象,代之以一个新类型的实例.代码如下: function SuperType() { this.pr

  • 关于Javascript闭包与应用的详解

    前言 Javascript闭包在学习过程中一般较难理解,本文从什么是闭包,常见闭包示例,闭包作用,闭包应用及闭包问题等方面来介绍闭包,希望能给大家带来更深层次的认识,有不恰当之处请指出,谢谢. 一.什么是闭包? 闭包是指一个嵌套的内部(子)函数引用了父函数作用域中数据的函数,这就产生了闭包. 关键理解: 1. 产生闭包必须要有嵌套函数 2. 闭包是函数,并是嵌套的内部函数 3. 闭包内部函数必须要引用父函数作用域中数据 如果不满足以上条件,则不能产生闭包,接下来示例说明. 1.1闭包满足条件代码

  • JavaScript闭包原理及作用详解

    目录 简介 闭包的用途 柯里化 实现公有变量 缓存 封装(属性私有化) 闭包的原理 垃圾收集 简介 实际开发中的优化 简介 说明 本文介绍JavaScript的闭包的作用.用途及其原理. 闭包的定义 闭包是指内部函数总是可以访问其所在的外部函数中声明的变量和参数,即使在其外部函 数被返回(寿命终结)了之后. 闭包的作用(特点) 1.函数嵌套函数 2.内部函数可以引用外部函数的参数或者变量 3.外部函数的参数和变量不会被垃圾回收,因为被内部函数引用. 闭包与全局变量 闭包的用途 柯里化 可以通过参

  • javascript常用经典算法实例详解

    本文实例讲述了javascript常用算法.分享给大家供大家参考,具体如下: 入门级算法-线性查找-时间复杂度O(n)--相当于算法界中的HelloWorld //线性搜索(入门HelloWorld) //A为数组,x为要搜索的值 function linearSearch(A, x) { for (var i = 0; i < A.length; i++) { if (A[i] == x) { return i; } } return -1; } 二分查找(又称折半查找) - 适用于已排好序的

  • javascript防篡改对象实例详解

    本文实例讲述了javascript防篡改对象.分享给大家供大家参考,具体如下: JavaScript中对象内置有多个属性Configurable,Writable,Enumerable,Value,Get和Set,来控制属性的行为.同样的ES5也有几个方法,来指定对象的行为.我们知道,javascript中的对象是可以共享的,也是默认可拓展的: //一旦将对象设置防篡改,就不能撤销了 //众所周知,一般的对象是可以随意拓展的 var person = {name:'liufang'}; pers

  • javascript原型模式用法实例详解

    本文实例讲述了javascript原型模式用法.分享给大家供大家参考.具体分析如下: 一般在了解了工厂模式和构造函数模式的弊端之后,就知道为什么需要原型模式了   原型模式i的定义:每个函数都有一个prototype(原型)属性,这个属性是一个对象,它的用途是包含可以由特定类型的所有实例共享的属性和方法.比如在构造函数模型中sayInformation()方法,如果声明两个实例就要构造两次sayInformation方法,但是声明两次是没有必要的,这就是为什么有原型模式的出现(尼玛,网上那些博客

  • javascript中this用法实例详解

    本文实例讲述了javascript中this用法.分享给大家供大家参考,具体如下: JavaScript中的this含义非常丰富,它可以是全局对象,当前对象或者是任意对象,这都取决于函数的调用方式.函数有以下几种调用方式:作为对象方法调用.作为函数调用.作为构造函数调用.apply或call调用. 对象方法调用 作为对象方法调用的时候,this会被绑定到该对象. var point = { x : 0, y : 0, moveTo : function(x, y) { this.x = this

  • Javascript闭包(Closure)详解

    下面就是我的学习笔记,对于Javascript初学者应该是很有用的. 一.变量的作用域 要理解闭包,首先必须理解Javascript特殊的变量作用域. 变量的作用域无非就是两种:全局变量和局部变量. Javascript语言的特殊之处,就在于函数内部可以直接读取全局变量. var n=999; function f1(){ alert(n); } f1(); // 999 另一方面,在函数外部自然无法读取函数内的局部变量. function f1(){ var n=999; } alert(n)

  • JavaScript队列的应用实例详解【经典数据结构】

    本文实例讲述了JavaScript队列的应用.分享给大家供大家参考,具体如下: 和前面介绍的栈相反,队列是一种先进先出的线性表,它只允许在表的一端进行插入,而在另一端进行删除.JavaScript自己提供了两个队列方法shift和push方法,分别是出队和入队,其原理就是将元素插入数组最后一个和删除第一个元素. 这里需要注意一点,就是unshift方法的效率比push的效率要低很多.因为它要将入队之前的数组全部往前移动一位.这里我们就不用代码再次演示了. 和线性表类似,队列也分为顺序队列和链队列

随机推荐