javaScirpt学习第五章(函数)-第二部分

发布于:2025-06-02 ⋅ 阅读:(21) ⋅ 点赞:(0)

javaScirpt学习第五章(函数)-第二部分

本次函数内容比较多,我们分了两不分。

  • window 对象
  • this 指向等问题

1、windows对象

Window对象

  • 在浏览器中,浏览器为我们提供了一个window对象,可以直接访问
    window对象代表的是浏览器窗口,通过该对象可以对浏览器窗口进行各种操作
    除此之外window对象还负责存储JS中的内置对象和浏览器的宿主对象
    • window对象的属性可以通过window对象访问,也可以直接访问
      函数就可以认为是window对象的方法

var 用来声明变量,作用和let相同,但是var不具有块作用域

  • 在全局中使用var声明的变量,都会作为window对象的属性保存
    • 使用function声明的函数,都会作为window的方法保存
      • 使用let声明的变量不会存储在window对象中,而存在一个秘密的小地方(无法访问)
      • var虽然没有块作用域,但有函数作用域

示例使用

当我们调用alert,console,confirm,xxx 时候,我们有没有想过,这些函数我们自己也没有定义,他们是怎么来的呢,其实在浏览器内部,有一个window对象负责管理这些所有的函数,包含默认的已经自定义的函数,都由这个统一管理

alert

alert(window);// object window

在这里插入图片描述

window.xx 使用

当我们声明了一个 var a = 10,实际上就是 window.a = 10 这种赋值操作;

  • 向window对象中添加的属性会自动成为全局变量

window.a = 10;

console.log(a);// 10

声明函数使用window对象

function fn() {
alert(‘我是函数fn’);
}

window.fn();

在这里插入图片描述

注意点

function fn2 () {

// var d = 22;//var虽然没有块作用域,但有函数作用域

d = 88;// 在局部作用域中,如果没有使用var或let声明变量,则变量会自动成为window对象的属性 也就是全局变量

}

fn2();//

console.log(d)//88

2、let和var以及函数执行顺序

变量的提升

  • 使用var声明的变量,它会在所有代码执行前被声明

    • 所以我们可以在变量声明前就访问变量

    函数的提升

  • 使用函数声明创建的函数,会在其他代码执行前被创建

    • 所以我们可以在函数声明前调用函数

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

变量提升

console.log(b);

var b = 10;// 在下面申明 undefined

//let b = 10;// 在下面申明 Cannot access ‘b’ before initialization

在这里插入图片描述

函数提升

fn();//我是fn函数方法-----》》》

//函数提升

function fn() {

console.log(‘我是fn函数方法-----》》》’)

}

对变量未声明

//var a = 10;

a = 10;// window.a = 10

3、小练习

<script>
   var a = 1;

   function fn() {
     a = 2;
     console.log(a);//2
   }

   fn();
   console.log(a);//2


   // 变量和函数的提升同样适用于函数作用域
   var a1 = 1;
   function fn1() {
     console.log("fn1-->",a1);//undefined
     var a1 = 2;
     console.log("fn1-->",a1);//2
   }

   fn1();
   console.log("a1-->",a1);//1


   // 定义形参就相当于在函数中声明了对应的变量,但是没有赋值
   var a2 = 22;
   function fn2(a2) {
     console.log("fn2-->",a2);//undefined
     a2 = 33;
     console.log("fn2-->",a2);//33
   }

   fn2();
   console.log("a2-->",a2);//22


   // 案例3
   var a3 = 33;
   function fn3(a3) {
     console.log('fn3-->',a3);//33

     a3 = 19;
     console.log('fn3-->',a3);// 19
   }

   fn3(a3);
   console.log('a3-->',a3);//19


   // 案例4 
   var a4 = 4;
   console.log('a4--->',a4);//4 

   // 函数名字叫 a4 
   function a4() {
     alert('fn--->a4')
   }
   console.log('a4--->',a4);//4 

   var a4 = 41;
   console.log('a4--->',a4);//41
   
   var a4 = function() {
      alert('fn--->a4->')
   }

   console.log('a4--->',a4);//函数内容


   var a4;
   console.log('a4--->',a4);//函数内容



</script>

4、debug 使用

debug就是用来调试程序,停留在某一段地方,让代码一行一行的执行,让我们看到程序的变化使用。

第一种使用方式

打开浏览器的F12 快捷键

在这里插入图片描述

在这里插入图片描述

第二种方式

debugger // 在代码中打了一个断点这个时候代码就停留在这里了;

在这里插入图片描述

5、立即执行函数

立即执行函数(IIFE)

  • 立即是一个匿名的函数,并它只会调用一次

  • 可以利用IIFE来创建一个一次性的函数作用域,避免变量冲突的问题

注意

  • 在开发中应该尽量减少直接在全局作用域中编写代码!

  • 所以我们的代码要尽量编写的局部作用域

  • 如果使用let声明的变量,可以使用{}来创建块作用域

示例使用

<script>
  // 使用let 申明变量  不使用var 
    {
      let a = 10;
    }

    {
      let a = 20;
    }

    //console.log(a);//a is not defined


    // 函数里面写var 这种有自己的作用域
    function fn1() {
       var b = 10;

    }
    fn1();
    //console.log('b==>',b);// b is not defined


    // 希望可以创建一个只执行一次的匿名函数
    (function() {
       let c = 10;
       console.log('c==>',c);//c==> 10
    }());


    // 注意,如果我们需要写两个函数,一定记得要在函数结束后面加上分号
    // ,或者加上其他逻辑,避免连接到一起而不能解析
     //方式2 括号写到外面  
     (function() {
       let c = 10;
       console.log('c==>',c);//c==> 10
    }) ()
</script>

6、this

  • 函数在执行时,JS解析器每次都会传递进一个隐含的参数
    这个参数就叫做 this
    • this会指向一个对象
    • this所指向的对象会根据函数调用方式的不同而不同
      1.以函数形式调用时,this指向的是window
      2.以方法的形式调用时,this指向的是调用方法的对象
  • 通过this可以在方法中引用调用方法的对象

示例使用

<script>
   function fn() {
     console.log(this === window);// true
     console.log('fn对象是什么',this)// Window 
   }


   fn();// window 对象
   window.fn();// 如上


   // 对象调用
   const obj1 = {name: '孙悟空'};
   obj1.test = fn;

   obj1.test();// {name: '孙悟空', test: ƒ}

   const obj2 = {name: '猪八戒',test: fn}
   obj2.test();//{name: '猪八戒', test: ƒ} this 取谁调用,调用的对象是谁


   const obj3 = {
     name: '唐僧',
     sayHello: function () {
       console.log(this.name)
     }
   }

   const obj4 = {
     name: '唐僧1',
     sayHello: function () {
       console.log(this.name)
     }
   }


   obj3.sayHello();//唐僧
   obj4.sayHello();//唐僧唐僧1


</script>

7、箭头函数

箭头函数:

([参数]) => 返回值

例子:

  • 无参箭头函数:() => 返回值

  • 一个参数的:a => 返回值

  • 多个参数的:(a, b) => 返回值

  1. 只有一个语句的函数:() => 返回值

  2. 只返回一个对象的函数:() => ({…})

  3. 有多行语句的函数:() => {

​ …

​ return 返回值

}

  • 箭头函数没有自己的this,它的this有外层作用域决定

  • 箭头函数的this和它的调用方式无关

示例使用

<script>
  // 普通函数this 
   function fn1() {
     console.log('fn1---->',this)
   }

   const fn2 = () => {
     console.log('fn2--->',this)
   }

   fn1();//Window
   fn2();//Window


   const obj = {
     name: '孙悟空',
     fn1,//fn1:fn1
     fn2,
     sayHello() {
       console.log(this.name)


       function t() {
         console.log('t--->',this)
       }

       t();//Window

       const t2 = () => {
         console.log('t2--->',this);
       }

       t2();// 指向的是对象
     }
   }

   obj.fn1();// obj对象
   obj.fn2();// window 对象


   obj.sayHello();

   // 总结,箭头函数的this是,谁调用我,那么我得this就是谁
   // 其他函数的this 不定,箭头函数的指向比较稳定

</script>

8、严格模式

JS运行代码的模式有两种:

  • 正常模式

    • 默认情况下代码都运行在正常模式中,
      在正常模式,语法检查并不严格
      它的原则是:能不报错的地方尽量不报错
    • 这种处理方式导致代码的运行性能较差
  • 严格模式

    • 在严格模式下,语法检查变得严格
      1.禁止一些语法
      2.更容易报错
      3.提升了性能
  • 在开发中,应该尽量使用严格模式,
    这样可以将一些隐藏的问题消灭在萌芽阶段,
    同时也能提升代码的运行性能

实例使用

<script>
   "use strict"//全局的严格模式
   let a = 10
   console.log(a)

  // b = 11;//b is not defined
  // console.log(b)

  // 函数里面使用严格模式
  function fn() {
     'use strict'
     //c = '123'//: c is not defined
  }

  fn()

</script>

网站公告

今日签到

点亮在社区的每一天
去签到