JavaScript 百炼成仙 读后感

100 阅读2分钟

作用域

JavaScript中作用域分为两种

全局作用域和函数作用域

全局作用域

function test(){
 console.log(a)
}
var a=10
test()//10

调用函数test 的时候,先从test内部作用域(当前是函数作用域)去寻找 变量a 如果找不到,再去父级作用域(当前 全局作用域)寻找,找到了变量a=10,所以结果为10

function test(){
 console.log(a)
}
test()//undefined
var a=10

调用函数test 的时候,全局作用域中变量var a=10 还没有执行,所以结果为undefined

函数作用域

function test(){
  var a=10
}
console.log(a)//undefined

因为var a=10 是在函数作用域中声明的 所以外部作用域调用a 的时候会访问不到 ,所以结果为undefined

当发生作用域嵌套的时候,只能里面的访问外面的,外面的无法访问里面的

作用域嵌套

var a=10

function test(){
  var a;

  var inner=function(){
      console.log(a)
  }

  inner();
  
}

test();//undefined

调用函数test 的时候,inner 需要打印变量 a,在inner内部没找到变量a,就向父级test 内部找,找到了只声明未赋值的变量a(var a;);所以结果为undefined

参数传递

function add(a,b,c) {
   var sum=a+b+c;
   console.log(sum)
}
add(1)//NaN

这种情况下,a等于1,b和c是undefined,所以1+undefined+undefined=NaN,结果为NaN,代表无法计算

function add(a,b,c) {
   console.log(arguments)//[1,2,3,4]
   var sum=a+b+c;
   console.log(sum)
}
add(1,2,3,4)//6


function add() {
   console.log(arguments)//[1,2,3,4]
   var a=arguments[0]
   var b=arguments[1]
   var c=arguments[2]
   var sum=a+b+c;
   console.log(sum)
}
add(1,2,3,4)//6

function add() {
   console.log(arguments)//[1,2,3,4]
   var sum=0;
   for(var i=0;i<arguments.length;i++){
    sum+=arguments[i]
   }
   return sum
}
var sum=add(1,2,3,4)
console.log(sum)//10

虽然 add 函数的入参个数和实际传入的个数不同,也不会报错,额外的参数会存在于 函数作用域中的arguments数组中 例如 代码中第4个入参4 存放在arguments[3]中

闭包

闭包形成

  1. 在函数内部也有一个函数

  2. 函数内部的函数里使用到外部函数的局部变量

  3. 外部函数把内部函数作为返回值return出去了

function add() {
   var sum=0;
   return function(a){
     sum+=a;
     console.log(sum)
   }
}
var inner=add();
inner(1);//1
inner(1);//2
inner(1);//3

闭包的好处是可以使局部变量sum 不会因为原函数调用结束后销毁,而是会一直存在,反复调用内部函数的时候就会发现局部变量sum一直存在,使用闭包可以减少很多不必要的全局变量,

但是闭包会导致变量一直不被释放,会导致内存泄露,可以在某一特定时刻 把变量赋值为null,JavaScript会扫描函数中值为null的变量,一旦找到就会自动清除这些无用的变量

自执行函数

语法:(定义一个没有名字的函数)();

通常和闭包配合使用

function add() {
   var sum=0;
   return function(a){
     sum+=a;
     console.log(sum)
   }
}
var inner=add();
inner(1);//1
inner(1);//2
inner(1);//3
 var inner=(()=>{
   var sum=0;
   return function(a){
     sum+=a;
     console.log(sum)
   }
})();
inner(1);//1
inner(1);//2
inner(1);//3

“new”一个函数

this永远指向当前函数调用者

 function hello(){
     console.log(this)
 }
 hello()//window

 function hello(){
     console.log(this)
 }
 new hello()//window

 function hello(){
     console.log(this)
 }
 var objhello=new hello()
console.log(objhello)

因为函数再使用 new 关键字后,函数内部会产生一个对象出来,而this就指向这个对象

对象是引用类型

回调函数

callback

 function hello(name,callback){
   var str= name+哈哈
     callback(str)
 }
hello('张三',(val)=>{
  console.log("你好"+val+"开心的一天")
})//你好张三哈哈开心的一天