自学内容网 自学内容网

3、函数定义,函数调用,this指向总结,闭包

一、函数的定义方式

1、函数声明

function demo1() {
  var num = 12
  var result = Math.pow(num,2)//指数函数
  return result
}

2、函数表达式

var demo2 = function (x,y) {
//内置对象arguments前面的两个参数  是 x,y
  var sum = arguments[0] + arguments[1]
  console.log(sum)
}

3、构造函数

var demo3 = new Function("x","y","return x+y")

二、函数的调用方式

1、函数名()

console.log(demo1())//144
demo(10,20)//30
var re = demo3(1.2,1.3)
console.log(re)//2.5

2、call() / apply()

console.log(demo1.call())//144
console.log(demo1.apply())//144
demo2.call(window, 1, 2)//3
demo2.apply(null, [4, 5])//9

3、自调用

函数表达式自调用

var fn1 = (function () {
  console.log('this is function')//this is function
})()

匿名函数

(function () {
  console.log('我是匿名函数')//我是匿名函数
})()

4、对象中的函数调用

var obj = {
  school: '学校',
  study: function () {
    console.log('我是对象的函数')//我是对象的函数
  },
}
//要用obj去调用  因为所属对象是obj
  obj.study()

5、数组中函数的调用

var arr = [10,'0',undefined,null,false,[2, 3],
    function () {
      console.log('我是函数也是数组的元素')//我是函数也是数组的元素
      console.log(this)
      //[10, '0', undefined, null, false, Array(2), ƒ, {…}]
    },
    {},
  ]
  arr[6]()

6、函数当做参数调用

function demo4(x) {
  x()
}
demo4(function () {
  alert('我是函数也是demo4的参数')//弹窗 我是函数也是demo4的参数
})

7、函数当做返回值的调用

function demo5() {
  return function () {
console.log('我是函数也是demo5的返回值')
  }
}
demo5()()

如果函数A的返回值是匿名函数B,想要调用匿名函数B 直接再函数A 后面加两个小括号

三、函数中this指向问题(总结)

  • 1、在普通函数中this指向window
function fn1() {console.log(this)}
fn1()//window
  • 2、在定时器函数中this指向window
var timer = setInterval(function(){
    console.log(this);//window
},2000)
  • 3、在事件函数中this指向事件源
var btn = document.getElementById("btn")
btn.onclick = function() {
  console.log(this)//btn
}
  • 4、在对象函数中this指向当前对象
var name = "this window"
var object = {
    name: 'this object',
    getName: function () {
    //this object在对象函数中this指向当前对象(this指向)
        console.log(this.name);
    console.log(name);//this window 当前没有  往上查找(作用域链查找)
    }
}
object.getName()
  • 5、在构造函数中this指向实例化对象
function Person(age,name) {
this.age = age
this.name = name
consoel.log(this)//this指向Person的实例对象p1
}
var p1 = new Person(18,;'张哈哈')
  • 6、在原型函数中
    • 如果原型调用,this指向原型
    • 如果实例化对象调用,this指向实例化对象
  • 7、在数组函数中this指向当前数组

四、闭包

1、作用域

有且只有函数 才可以产生作用域

全局作用域(永恒作用域)

  • 全局变量
  • 在任何作用域内都有效
  • 生命周期:浏览器打开时创建,关闭时销毁

局部作用域

  • 局部变量
  • 只在当前作用域内有效
  • 生命周期:函数调用时创建,调用完成后销毁

2、闭包的定义?

  • 定义在函数内部的函数

3、闭包的作用?

获取父函数内部的变量

console.log(count)//获取不到  因为count是局部的
var num = 15
function parent() {
  console.log(num)//15 num是全局的
  var count = 12.4
  // 闭包函数的本质
  // 局部作用域--parent,相对于child作用域是永恒的,本身是作用域是短暂的 
  function child() {
  //  局部作用域--child
  console.log(count)
  }
  child()
}
parent()

锁住父函数内部的变量

// 随机数案例
var getRandom = function (min, max) {
    var num = Math.floor(Math.random() * (max - min) + min)
    return function(){
        console.log(num);
    }
}
var result = getRandom(10, 20)
// 两次结果一样 因为父元素执行一次 
result()
result()
var btn = document.getElementById("btn")
btn.onclick = (function () {
  var count = 0
  return function () {
    count++
    console.log(this)
    //由于事件是异步的,所以自调用的是父函数,此时父函数是匿名函数,所以单击事件调用闭包函数
    this.innerText = "点赞(" + count + ")"
  }
})()

image-20240226195738360

var list = document.querySelectorAll("#list>li")
for (var i = 0; i < list.length; i++) {
    (function (i) {
        setTimeout(function () {
            console.log('索引:'+i);
            console.log('文本值:'+list[i].innerText);
        },3000)
    })(i)
}
image-20240227094051418

4、闭包函数的本质?

  • 让父函数相对于闭包函数是永恒作用域

5、闭包作用域之获取复函数内部变量

  • this 指向 作用域链的查找规则 预解析 闭包
var name = "this window"
var object = {//不会产生作用域
     name: 'this object',
     getName: function () {//局部作用域
        console.log(this.name);//在对象函数中this指向当前对象
        console.log(name);//在当前作用域查找  undefined
        var name = "this getName"//var name提升
        return function () {
            console.log(this.name);//普通函数 this指向window
            console.log(name);//this getName  当前作用域没有 往上一级查找
        }
    }
} 
object.getName()()
var name = "this window"
var object = {//不会产生作用域
    name: 'this object',
    getName: function () {//局部作用域
        console.log(this.name);//this object 在对象函数中this指向当前对象
        console.log(name);//在当前作用域查找  undefined
        var name = "this getName"//var name提升
        return function () {
            function name(){
                console.log('我是函数声明');
            }
            var name = function () {
                console.log(this.name);//普通函数指向window
            }
        //this object  因为this 指向bind(this)中的this bind的指向object
            console.log(this.name);
            console.log(name);//this getName函数  当前作用域有name 函数表达式覆盖函数声明
            name()
        }.bind(this)
        return name
    }
}
object.getName()()

五、闭包练习题

var x = 11
function fn(x) {
    //形参x  相当于var x = 2
    console.log(x);//2   fn(2)实参传给x
    x = 10
    console.log(x);//10 x重新赋值为10
    rguments[0] = 20   //fn的第一个参数是x  所以x重新赋值为20
    onsole.log(x);//20  

fn(2)
console.log(x);//11 全局作用域
var x = 11
function fn(x) {
    //相当于 var x  没赋值
    console.log(x);//undefined
    x = 10
    console.log(x);//10
    // console.log(arguments); 数组元素是实参
    arguments[0] = 20
    console.log(x);//10
}
fn()
console.log(x);//11 全局作用域
var x = 11
function fn(x) {
    // var x = 11
    console.log(x);//11
    x = 10
    console.log(x);//10
    arguments[0] = 20
    console.log(x);//20
}
fn(x)//11
console.log(x);//11  

原文地址:https://blog.csdn.net/m0_58779986/article/details/136309167

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!