美文网首页
javascript作用域和作用域链

javascript作用域和作用域链

作者: 原上的小木屋 | 来源:发表于2019-03-08 15:52 被阅读0次

立即执行函数表达式是什么?有什么作用?

  • 立即执行函数就是
  1. 声明一个匿名函数
  2. 马上调用这个匿名函数
  • 立即执行函数有什么用?
  1. 只有一个作用:创建一个独立的作用域。
  2. 这个作用域里面的变量,外面访问不到(即避免「变量污染」)。

求n!,用递归来实现。

function factorial(n){
    if(n==1){return 1}
    return n*factorial(n-1)
}

以下代码输出什么?

    function getInfo(name, age, sex){
        console.log('name:',name);
        console.log('age:', age);
        console.log('sex:', sex);
        console.log(arguments);
        arguments[0] = 'valley';
        console.log('name', name);
    }

    getInfo('飞天虎', 2, '男');
    getInfo('小虎', 3);
    getInfo('男');
  1. getInfo('飞天虎', 2, '男');输出
  • name: 飞天虎
  • age: 2
  • sex: 男
  • ["飞天虎", 2, "男"]
  • name valley
  1. getInfo('小虎', 3);输出
  • name: 小虎
  • age: 3
  • sex: undefined
  • ["小虎", 3]
  • name valley
  1. getInfo('男');输出
  • name: 男
  • age: undefined
  • sex: undefined
  • ["男"]
  • name valley

写一个函数,返回参数的平方和?

var sum=0;
for(i=0;i<arguments.length;i++){sum=sum+arguments[i]**2}
return sum;

如下代码的输出?为什么?

    console.log(a);
    var a = 1;
    console.log(b);
  1. console.log(a)输出undifined
  • 声明提前,会将第二行的var a提至最前方,只是先起到声明作用,但是赋值a=1并未提前,console.log(a)时a的值为undifined,这样console.log(a)的时候就输出undifined
  1. console.log(b)会报错
  • 而b变量未声明就输出必然会报错

如下代码的输出?为什么?

    sayName('world');
    sayAge(10);
    function sayName(name){
        console.log('hello ', name);
    }
    var sayAge = function(age){
        console.log(age);
    };
  1. sayName('world') 会输出 hello world
  • 函数声明在JS解析时进行函数提升,因此在同一个作用域内,不管函数声明在哪里定义,该函数都可以进行调用
  1. sayAge(10)会报错
  • 函数表达式也存在变量提升,不过与前者区别的是,前者会将整个函数体视为变量进行变量提升,而函数表达式只会将函数名即sayName进行提升,因为其未被赋值,还是undefined,因此会报错

写一个函数squireArr,其参数是一个数组,作用是把数组中的每一项变为原值的平方

var arr = [3, 4, 6]
function squireArr( arr ){
  for(i = 0 ; i < arr.length ; i++){ arr[i] = arr[i]**2 }
}
squireArr(arr)
console.log(arr)  // [9, 16, 36]

如下代码的输出?为什么?

var x = 10
bar() 
function foo() {
  console.log(x)
}
function bar(){
  var x = 30
  foo()
}
  • 输出10
  • 首先两个函数foo和bar会声明前置,运行到bar的时候,进入bar的作用域,接着进入foo的作用域,foo函数里面输出x,但是x并没有在foo函数内部声明,向上层找到x = 10,输出10

写一个函数squireArr,其参数是一个数组,返回一个新的数组,新数组中的每一项是原数组对应值的平方,原数组不变

var arr = [3, 4, 6]
function squireArr( arr ){
    var newArr = [];
    for(var i = 0; i < arr.length; i++){
        newArr[i] = arr[i] * arr[i];
    }
    return newArr;
}
var arr2 = squireArr(arr)
console.log(arr)  // [3, 4, 6]
console.log(arr2)  // [9, 16, 36]

如下代码的输出?为什么?

var x = 10;
bar() 
function bar(){
  var x = 30;
  function foo(){
    console.log(x) 
  }
  foo();
}    
  • 输出30

如下代码的输出?

var a = 1
function fn1(){
  function fn2(){
    console.log(a)
  }
  function fn3(){
    var a = 4
    fn2()
  }
  var a = 2
  return fn3
}
var fn = fn1()
fn() //输出多少
  • 输出2

如下代码的输出?

var a = 1
function fn1(){
  function fn3(){
    var a = 4
    fn2()
  }
  var a = 2
  return fn3
}
function fn2(){
  console.log(a)
}
var fn = fn1()
fn() //输出多少
  • 输出1

如下代码的输出?为什么?

var a = 1
function fn1(){

  function fn3(){
    function fn2(){
      console.log(a)
    }
    fn2()
    var a = 4
  }
  var a = 2
  return fn3
}
var fn = fn1()
fn() //输出多少
  • 输出undefined
  • 先进入fn3作用域,作用域内a变量提升,即为var a,此时fn3作用域内的a还是undefined便进入fn2作用域
  • 进入fn2作用域,要求输出a,fn2作用域内没找到,向上层找到了fn3作用域,此时还是undefined,即输出undefined

如下代码的输出?为什么?

var obj1 = {a:1, b:2};
var obj2 = {a:1, b:2};
console.log(obj1 == obj2);
console.log(obj1 = obj2);
console.log(obj1 == obj2);
  1. 第一个console.log()输出false
  • 对象属于引用类型值,保存的是指向对象的指针,因此输出false
  1. 第二个console.log()输出{a:1,b:2}
  2. 第三个console.log()输出true
  • 将obj2赋值给obj1,即相当于obj1也指向了obj2指向的对象,地址相同,因此输出true

如下代码的输出?为什么?

var a = 1
var c = { name: 'jirengu', age: 2 }

function f1(n){
  ++n
}
function f2(obj){
  ++obj.age
}

f1(a) 
f2(c) 
f1(c.age) 
console.log(a) 
console.log(c)     
  1. 第一个console.log(a)输出1
  • number属于基本类型值,保存的是简单数据段( 数值 )
  • 因此在f1(a)调用过程后,a值不变,最终输出1
  1. 第二个console.log(c)输出{name: "jirengu" , age : 3}
  • 对象属于引用类型值,保存的是指向对象的指针
  • f2(c)调用后,age对应的值已经变为3,f1(c.age)调用过程中传入的参数只是一个数值,而不是对象,因此age对应的值并未改变

写一个深拷贝函数。

function deepcopy(oldobj){
        var newobj={};
        for(var key in oldobj){
               if(typeof(key)=='object'){newobj[key]=deepcopy(oldobj[key])}
        else{newobj[key]=oldobj[key]}  
        }
        return newobj
}

相关文章

  • javascript基础知识问答-作用域和闭包

    1.理解词法作用域和动态作用域2.理解JavaScript的作用域和作用域链3.理解JavaScript的执行上下...

  • 作用域和闭包

    一、理解 JavaScript 的作用域、作用域链和内部原理 作用域 javascript 拥有一套设计良好的规则...

  • JS_0: 执行环境和作用域链

    JavaScript,目前对于执行环境和作用域链的理解 什么是作用域链? 要讲作用域链就得先讲执行环境。 每个函数...

  • JavaScript深入系列的学习(一)

    JavaScript深入之从原型到原型链JavaScript深入之词法作用域和动态作用域JavaScript深入之...

  • JavaScript 函数闭包(colsure)

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

  • 2018-04-11

    JavaScript作用域链浅析 1、作用域 作用域指的是变量存在的范围。在ES5规范中,JavaScript只有...

  • 一网打尽 JavaScript 的作用域

    JavaScript 的作用域包括:模块作用域,函数作用域,块作用域,词法作用域和全局作用域。 全局作用域 在任何...

  • JavaScript作用域分类

    JavaScript作用域分类全局作用域局部作用域函数作用域块级作用域catchwithlet 和 const 什...

  • 基于JavaScript作用域链的性能调优

    JavaScript作用域和作用域链,说起来很简单,但是细细分析,大有玄机。只能真正理解了作用域链原理,才能写出更...

  • 07-JavaScript作用域和预解析

    JavaScript作用域 JavaScript中有全局作用域和局部作用域 相同作用域内不能有同名的变量和函数 不...

网友评论

      本文标题:javascript作用域和作用域链

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