10.Window对象&提升

Window对象

  • 在浏览器中,浏览器为我们提供了一个window对象,可以直接访问
  • window对象代表的是浏览器窗口,通过该对象可以对浏览器窗口进行各种操作
    • 除此之外window对象还存储JS中的内置对象和浏览器的宿主对象(浏览器所提供的对象,例如alert())
  • window对象的属性可以通过window对象访问,也可以直接访问
  • 函数可以认为是window对象的方法
  • 向window对象中添加的属性会自动成为全局变量
        function fn2(){}
        console.log(fn2 == window.fn2) //true        

        window.c = "我是c"
        console.log(c); //我是c

var用来声明变量,作用和let相同,但var不具有块作用域(但有函数作用域)

  • 在全局中使用var声明变量,都会作为window对象的属性保存
  • 使用let声明的变量不会存储在window对象中,而是存储在一个秘密的小地方(同为全局变量优先访问)
        var a = "我是a"
        let b = "我是b"
        console.log(a == window.a) //true
        console.log(b == window.b) //false

补充

  • 使用function声明的函数,都会作为window的方法保存
  • 在局部作用域中,如果没有使用var或let声明变量,则变量会自动成为window对象属性,也就是全局变量(不建议这样写)
 <script>
        function fn1() {
            d = "我是fn1" //未声明,默认为window对象的属性,成为全局变量
        }
        fn1() //应为局部作用域声明的变量只有在调用的时候创建,所以要调用fn1,此时d变量创建成功
        console.log(d);
        console.log(fn1 == window.fn1) //true,fn1函数为window对象的方法
</script>

 提升(一点用没有)

但面试就喜欢问一些没用的东西,没有的你都知道那有用的你肯定也会。

  • 什么是提升?

就是在其他代码执行前先被拿出来执行

  • 为什么要提升呢?

主要是解决空间分配的问题,提前把变量函数拿出来根据他们的大小预留足够的空间,提高代码的质量。不只是JS其他语言也都有“提升”

1. 变量的提升

  • 使用var声明变量,它会在所有代码执行前被声明
  • 所以我们可以在变量声明前就访问变量(此时变量存在但未赋值是undefined)
<script>
        console.log(a);
        
        //a = 10 //window.a = 10 //a is not defined
        var a = 10 //undefined
</script>

2. 函数的提升

  • 使用函数声明创建的函数,会在其他代码执行前被创建
  • 所以我们可以在函数声明前调用函数
        fn() //我是fn函数
        function fn() {
            console.log("我是fn函数")
        }

        fn1() //fn1 is not a function,这里只是变量fn1被提升,fn1并未赋值
        var fn1 = function () {
            console.log("我是fn1函数");
        }
        //注意:必须是function开头的函数才能提前调用

3. let声明的变量实际也会提升,但是在赋值之前解释器禁止对该变量访问

练习1

<script>
        var a = 1
        function fn() {
            a = 2 //给a赋值,先找到a,由于这里并没有对a声明,所以向上一层找。找到var a = 1,对a重新赋值为2
            console.log(a); //2
        }
        fn()
        console.log(a); //2
</script>

练习2

 <script>
        //变量和函数的提升同样适用于函数作用域
        var a = 1
        function fn() {
            console.log(a); //undefined
            //这里a为局部变量,受函数体限制不能被外界访问,和外界互不干涉
            var a = 2
            console.log(a); //2
        }
        fn()
        console.log(a); //1
</script>

练习3

<script>
        //定义形参就相当于在函数中声明了对应的变量,但没有赋值
        var a = 1
        function fn(a) {
            console.log(a); //undefined
            //给形参赋值
            a = 2
            console.log(a); //2
        }
        fn()
        console.log(a); //1
</script>

练习4

<script>
        //定义形参就相当于在函数中声明了对应的变量,但没有赋值
        var a = 1
        function fn(a) {
            console.log(a); //1
            //给形参赋值,形参是局部变量,并不会影响外部的全局变量a
            a = 2
            console.log(a); //2
        }
        fn(a)//将全局变量a的值传给fn的形参a
        console.log(a); //1
</script>

练习5

<script>
        console.log(a); //ƒ a() {alert(2)}

        var a = 1 //执行

        console.log(a); //1

        function a() { //不执行,被提前执行过了
            alert(2)
        }

        console.log(a); //1

        var a = 3 //执行

        console.log(a); //3

        var a = function () { //执行,只有function a() {}形式函数会被提前
            alert(4)
        }

        console.log(a); //ƒ a() {alert(4)}

        var a //不执行,被提前执行过了

        console.log(a); //ƒ a() {alert(4)}
</script>

 

posted @ 2022-11-09 17:02  莫扎特03  阅读(23)  评论(0编辑  收藏  举报