01. this的典型应用场景
02. this的具体使用
03. 如何理解闭包?

01. this的典型应用场景

this在各个场景中取什么值,是在函数执行的时候确认的,不是在定义的时候确认的。

  • 普通函数执行 返回window
function fn1() {
    console.log(this)
}
fn1() // window
  • 使用 call apply 传入什么绑定什么
//call/bind可以改变this指向
function fn1() {
    console.log(this)
}
fn1.call({x:100})  //{x:100}
const fn2 = fn1.bind({x:200})
fn2()  //{x:200}
  • 作为对象方法执行 返回对象本身
const zhangsan = {
    name: \'张三\',
    sayHi() {
        // this 即当前对象
        console.log(this)
    },
    wait() {
        setTimeout(function(){
            // setTimeout本身触发的执行,所以this即是window
            console.log(this)
        })
    }
}
  • 箭头函数方法执行

箭头函数永远是取他上级作用域的this

const zhangsan = {
    name: \'张三\',
    sayHi() {
        // this 即当前对象
        console.log(this)
    },
    wait() {
        setTimeout(() => {
            // 箭头函数永远是取他上级作用域的this
            console.log(this)
        })
    }
}
  • class中的值 返回当前实例本身
class People {
    constructor(name) {
        // 正在创建的实例
        this.name = name
        this.age = 30
    }
    sayHi() {
        //张三的实例
        console.log(this)
    }
}
const zhangsan = new People(\'张三\')
zhangsan.sayHi()  //zhangsan对象
02. this的具体使用
  • 在html元素事件属性中使用
<input type="button" onclick="showInfo(this)" value="点击一下"/>
  • 构造函数
function Animal(name,color) {
    this.name = name;
    this.color = color;
}
  • input点击,获取值
<input type="button" id="text" value="点击一下">
<script type="text/javascript">
    var btn = document.getElementById("text")
    btn.onclick = function() {
        alert(this.value);  //此处的this是按钮元素
    }
</script>
  • apply()/call()求数组最值
var numbers = [5, 458, 120, -215]
var maxInNumbers = Math.max.apply(this.numbers)
console.log(maxInNumbers)  //458
var maxInNumbers = Math.max.call(this, 5, 458, 120, -215)
console.log(maxInNumbers)  //458

  • 手写bind函数
function fn1(a,b,c) {
    console.log(\'this=\', this)
    console.log("a b c=",a, b,c)
    return \'this is fn1\'
}
const fn2 = fn1.bind({x:100}, 10, 20, 30)
const res = fn2()
console.log("res=",res)

//返回值
// this= {x: 100}
//a b c=  10 20 30
// res= this is fn1

// 模拟bind
Function.prototype.bind1 = function() {
    // 将参数拆解为数组
    const args = Array.prototype.slice.call(arguments)
    
    //获取this(数组第一项)
    const t = args.shift()
    
    //fn1.bind(...) 中的fn1
    const self = this
    
    //返回一个函数
    return function () {
        return self.apply(t, args)
    }
}

function fn1(a,b,c) {
    console.log(\'this\',this)
    console.log(a,b,c)
    return \'this.is fn1\'
}

const fn2 = fn1.bind1({x:100},10,20,30)
const res = fn2()
console.log(res)
03. 如何理解闭包?
  1. 闭包定义和用法:当一个函数的返回值是另一个函数,而返回的那个函数如果调用了其父函数内部的其它变量,如果返回的这个函数在外部被执行,就产生了闭包。
  2. 表现形式:使函数外部能够调用函数内部定义的变量,有两种表现一种是函数作为参数被传递,一种是函数作为返回值被返回闭包,自由变量的查找,是在函数定义的地方,向上级作用域查找,不是在执行的地方。
// 函数作为返回值
function create() {
    const a = 100
    return function () {
        console.log(a)
    }
}
const fn = create()
const a = 200
// 函数作为参数被传递
function print(fn) {
    const a = 200
    fn()
}
const a = 100
function fn() {
    console.log(a)
}
pint(fn)  //100
  1. 实例如下
  • 作用域链,当前作用域没有声明变量,会向上一级找,找到就返回,没找到就一直找,直到window的变量,这种一层一层的关系就是作用域链。
  • 自由变量,一个变量在当前作用域没有定义,但是被使用了,就会向上级作用域,一层一层依次寻找,直到找到为止。如果全局作用域都没有找到,则报错 xx is not defined。
//这里明显count是函数内部的flag2的那个count。
var count=10; //全局作用域 标记为flag1
function add(){
    var count=0; //函数全局作用域 标记为flag2
    return function(){
        count+=1; //函数的内部作用域
        alert(count);
    }
}
var s = add()
s();//输出1
s();//输出2

  1. 变量的作用域
  • 作用域代表变量合法的使用范围,要理解闭包,首先必须理解JavaScript特殊的变量作用域。
  • 作用域分,全局作用域、函数作用域、块级作用域(ES6新增)
  • 变量的作用域分类:全局变量和局部变量。
  • 特点:

a. 函数内部可以读取函数外部的全局变量,在函数外部无法读取函数内部的局部变量。

b. 函数内部声明变量的时候,一定要使用var命令。如果不用的话,你实际上声明了一个全局变量。

  1. 使用闭包的注意点
  • 滥用闭包,会造成内存泄漏。 由于闭包会使得函数中的变量都被保存在内存中,内存消耗很大,所以不能滥用闭包,否则会造成网页的性能问题,在IE中可能导致内存泄露。解决方法是,在退出函数之前,将不使用的局部变量全部删除。
  • 会改变父函数的内部变量的值。 所以,如果你把父函数当作对象(object)使用,把闭包当作它的公用方法(Public Method),把内部变量当作它的私有属性(private value),这时一定要小心,不要随便改变父函数内部变量的值。
  1. 闭包的应用
  • 隐藏数据不让外边进行改变。非常常用的方式
//做一个缓存的小插件
function createCache() {
    const data = {} //闭包中的数据,被隐藏,不被外界访问呢。
    return {
        set: function (key, val) {
            data[key] = val
        },
        get: function (key) {
            return data[key]
        }
    }
}
const c = createCache()
c.set(\'a\', 100)
console.log(c.get(\'a\')

版权声明:本文为chenfengbiji原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/chenfengbiji/p/14334558.html