js小知识点串讲

2017-10-12  本文已影响20人  YM雨蒙

变量的生命周期

//问题一: 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

变量(声明)提升

就喜欢例子

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

上一篇 下一篇

猜你喜欢

热点阅读