美文网首页
js小知识点串讲

js小知识点串讲

作者: YM雨蒙 | 来源:发表于2017-10-12 22:48 被阅读20次

变量的生命周期

  • 看几个小例子
//问题一: 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中使用立即执行函数就可以打印出我们需要的东西

  • 立即执行函数创造了新的作用域
  • 造成上面的原因是闭包
  • 闭包作用暴露局部变量

相关文章

  • js小知识点串讲

    变量的生命周期 看几个小例子 总结一下: 默认作用域消失时,内存就被回收 如果内存被引用着,则不能回收 var 作...

  • js小知识点

    js小知识点 整理 js小知识点 (一):获取元素 1:document.getElementById('id名'...

  • 小知识点集汇一

    小知识点集汇一 小知识点 node接口模拟返回 js接口模拟数据 mockjs mocha js 测试框架--教程...

  • 微信小程序(七)小程序内嵌和require和拿到app全局变量

    (一) 本节知识点 小程序内嵌JS 代码 小程序require (二) 小程序内嵌JS代码 必须用wxs标签和 m...

  • 『黑马程序员济南』JavaEE就业笔记串讲--JavaScrip

    『黑马程序员济南』JavaEE就业笔记串讲--JavaScript JS的概述 Ø什么是JavaScript: 运...

  • 前端小知识点综合大全

    小知识点 node接口模拟返回 js接口模拟数据 mockjs mocha js 测试框架--教程 git 教程 ...

  • 专升本―8天

    Man proposes , god disposes 今天依然串讲英语,复习之前的知识点。 把定语从句,非谓语之...

  • react学习(2)

    知识点 1:babel.js的作用:ES6=>ES5,jsx=>js2:小案例

  • 耐心是最好的教育

    今天让学生串讲书上的知识点 我告诉了他们串讲的方法,可是一位学生讲的时候很不合我的心意,和我的预期相差甚远! 我内...

  • 第七次课程,马靖

    1、在这节课最重要印象最深刻的三个部分/知识点? (1)高华同学的课前串讲 (2)记忆的知识点 (3)遗忘的知识点...

网友评论

      本文标题:js小知识点串讲

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