js小知识点串讲

变量的生命周期

  • 看几个小例子
//问题一: a什么时候被赋值,或者a什么时候出现在内存中?什么时候消失?

<script>
  var a = 1  //当代码执行到这一行时才有1
  // => window.a = 1   所以当页面关闭时a消失,或者刷新又有了新的a
</script>
//问题二:  a什么时候被赋值,或者a什么时候出现在内存中?什么时候消失?

<script>
  function fn(){
    var a = 1    //当函数调用后a才出现
  }
  //浏览器执行到这一行
  fn()  //执行完成以后a消失
  // fn() 重新调用,重新赋值a
</script>
//问题三: 如果a被引用者,a什么时候被赋值,或者a什么时候出现在内存中?什么时候消失?

<script>
  function fn(){
    var a = {name : 2}   //执行完不会消失,因为被引用,当window页面关闭,消失
    var b = 2  // 执行完就消失了,因为没有东西引用它
    window.f = a
  }
  fn()  
  console.log(window.f)  //1
  window.f = {name : 3}  //a没有被引用,消失
</script>

总结一下:

  • 默认作用域消失时,内存就被回收
  • 如果内存被引用着,则不能回收

var 作用域

  • 就近原则
  • 词法作用域
  • 同名的不同变量

一直觉得看例子最直接

//问题一: a=1,指的是哪个a

<script>
  var a
  function f1(){
    var a 
    function f2(){
      var a  //同一作用域级的a 就近原则
      a = 1
    }
  }
//函数同理
  function f2(){}
  function f1(){
    function f2(){
      f2()  //指向父级f2
    }
  }
</script>
<script>
//词法作用域 ,不同作用域的a是不同的变量
  var a
  function f1(){
    var a 
    function f2(){
      var a 
      f3()
      a = 1
    }
  }
  function f3(){
    a = 2 //指向第一个a
  }

立即执行函数

-想得到一个独立的作用域.声明一个函数

fucntion f1(){
  var a
  a = 1
  console.log(a)
}
f1()
=>
//但是我想不想要全局变量f1怎么办啊,改一下
function (){
  var a
  a = 1
}()   //语法会报错?怎么办呢
=>
(function (){
  var a
  a = 1
})()   
或者
!function (){
  var a
  a = 1
}()   //需要的是一个独立的作用域

函数前面可以加 + - ~ 都可以成为立即执行函数
//立即执行函数可以加参数
var a = 100
!function (a){  //形参声明的变量,值是第一个参数
  var a = arguments[0]
  var a
  a = 1
console.log(a)   //1
}(/*没有参数*/)
console.log(a)  //100 

var a = 100
!function (a){
  console.log(a)  //99 新的作用域
}(99)
//问题: 实参a 和形参a 是同一个a 吗?
var a = 100
!function (a){  //新声明的a,只是恰好名字相同,a可以是b,c,i,h不同的名字
  console.log(a) //100 赋值时var a =100
}(a)  //这个a是var a = 100

变量(声明)提升

  • 浏览器在执行代码之前,会先把所有声明提升到作用域的顶部
  • 你却从来不知道去提升一下变量
  • 只要你提升变量,面试题就是小 case

就喜欢例子

// 问题: a 的值是多少
var a = 100
function a(){}
==>
var a
function a(){}
a = 100
console.log(a)  // 100
//问题: a 的值是什么
var a = 100
var a = function (){}
function a(){}

console.log(a)
// 以下代码执行时,三次打印分别输出什么?为什么?手动提升作用域
 
function add1(i){
  console.log("函数声明:"+(i+1));
}
add1(1);  // 101
 
var add1 = function(i){
  console.log("函数表达式:"+(i+10));
}
add1(1);  // 11
 
function add1(i) {
    console.log("函数声明:"+(i+100));
}
add1(1);  // 11

时机(异步)

button.onclick = function(){
  console.log("A") //当用户操作,才打印
}
console.log("B")  //先打印

还有setTimeout

复习了上面那么多只是,就是为了做一些面试题目:

<ul>
  <li>选项1</li>
  <li>选项2</li>
  <li>选项3</li>
  <li>选项4</li>
  <li>选项5</li>
  <li>选项6</li>
</ul>

var items = document.querySelectorAll('li')

for(var i=0; i<items.length; i++){
   items[i].onclick = function(){
     console.log(i)  //每次结果都是li的长度,为什么呢??
   }
}

==>
//提升一下变量,在观察
var items
var i
items = document.querySelectorAll('li')
for(i=0; i<items.length; i++){
  //i = 0,1,2,3,4,5,6
  items[i].onclick = function(){
    console.log(i)  //点击每一次打印都是6 怎么解决这个问题呢?
  }
}
console.log(i)  //6
var items
var i
items = document.querySelectorAll('li')
for(i=0; i<items.length; i++){
  //创建一个函数作用域
  var temp = function(j){
    console.log(j)
  }
  //把函数i作为参数传进去,得到的是6个不同的值
  temp(i)   //i = 0,1,2,3,4,5

  items[i].onclick = function(){
    console.log(i)
  }
}

==> 再改一下
var items
var i
items = document.querySelectorAll('li')
for(i=0; i<items.length; i++){
  //创建一个函数作用域
  var temp = function(j){
    // j1 = 0, j2 = 1 ...
    console.log(j)
    items[j].onclick = function(){
      // 每点击一次,出现的值不同
      console.log(j)
    }
  }
  //把函数i作为参数传进去
  temp(i) 
}

==>

var items
var i
items = document.querySelectorAll('li')
for(i=0; i<items.length; i++){
  //立即执行函数
 !function(j){
    items[j].onclick = function(){
      // 每点击一次,出现的值不同
      console.log(j)
    }
  //i作为参数传进去
  }(i)
}

另一种方法

//修改一下上面
var items
var i
items = document.querySelectorAll('li')
for(i=0; i<items.length; i++){
  function temp(j){
    //return一个函数
    return function(){
      console.log(j)
    }
  }
  var fn = temp(i)  //创建一个新的作用域
  items[i].onclick = fn  //等于一个函数
}

==>

var items
var i
items = document.querySelectorAll('li')
for(i=0; i<items.length; i++){
  items[i].onclick = function(i){
    //return一个函数
    return function(){
      console.log(i)
    }
  }(i)
}

又一个题目

var fnArr = [];
for (var i = 0; i < 10; i ++) {
  fnArr[i] =  function(){
    return i
  };
}
//var fn = fnArr[3]
//fn()  调用时才有i,先执行for循环

console.log( fnArr[3]() ) // 10,怎么输出1,2,3...,9
var fnArr = []
for (var i = 0; i < 10; i ++) {
  fnArr[i] =  (function(j){
    return function(){
      return j
    } 
  })(i)
}
console.log( fnArr[3]() ) // 3

var fnArr = []
for (var i = 0; i < 10; i ++) {
  (function(i){
    fnArr[i] =  function(){
      return i
    } 
  })(i)
}
console.log( fnArr[3]() ) // 3

//使用ES6语法let,创建一个作用域
var fnArr = []
for (let i = 0; i < 10; i ++) {
  fnArr[i] =  function(){
    return i
  } 
}
console.log( fnArr[3]() ) // 3

我们做了两个面试题目,发现在ES5中使用立即执行函数就可以打印出我们需要的东西

  • 立即执行函数创造了新的作用域
  • 造成上面的原因是闭包
  • 闭包作用暴露局部变量
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,752评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,100评论 3 387
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 159,244评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,099评论 1 286
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,210评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,307评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,346评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,133评论 0 269
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,546评论 1 306
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,849评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,019评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,702评论 4 337
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,331评论 3 319
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,030评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,260评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,871评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,898评论 2 351

推荐阅读更多精彩内容

  • 1. Java基础部分 基础部分的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法,线程的语...
    子非鱼_t_阅读 31,605评论 18 399
  • 不曾在你巅峰时慕名而来,也未曾在你低谷时离你而去,我生活在你的时代,当然会做好准备,等着你的王者归来。
    蜂鸟1号阅读 286评论 0 0
  • 北方的秋雨总是要冰冷些的,蜷缩在搞搞的毛领里,踏着细雨前行。找到那家名做乐水名苑的地方。 很难想象繁闹商业区地带有...
    白鹿依依Batlu阅读 1,383评论 1 0
  • 夜晚 空荡的街道 一个人散步的生活 曾经 热闹的人海 两个人牵手的时光 如今 路过的风景 枯萎的花草,寂寞的白云 ...
    阿琴姑娘阅读 1,008评论 51 100