this 关键字

  1. this指向什么和书写的位置没有关系,和调用方式有关系
  2. this 是在产生EC时动态绑定的

绑定规则

  1. 默认绑定 普通函数
    1. 独立函数调用,可以理解成函数没有被绑定到某个对象上
    2. 独立函数调用, 函数内部的this指向window
var obj = {name:'boo',fn:function(){console.log(this)}}
var fn = obj.fn
fn() //this → window  //独立函数调用
  1. 隐式绑定 对象的方法
    1. 通过某个对象进行调用,也就是调用位置是通过某个对象发起的函数调用
    2. this指向调用者
var obj = {name:'boo',fn:function(){console.log(this)}}
obj.fn() //this → obj
  1. 显示绑定 函数也是对象
    1. 函数也是一个对象, 对象是属性的无序集合
    2. call
      1. 显示绑定
      2. 让函数执行 //fn.call(obj)
      3. call 传参:从第二个参起, 传递的参数就会传递给函数
    3. apply 和call一样 参数格式不一样 以数组方式传递
    function gn(num1,num2){console.log(num1+num2)}
    let obj = {name:'bool'}
    gn.call(obj,100,200)  
    gn.apply(obj,[100,200])
    
    1. bind
      1. 显示绑定
      2. 也可以传参
      3. 但是函数不会执行
      4. 返回一个绑定this的新函数
    function gn(num1,num2){console.log(this,num1+num2)}
    let obj = {name:'bool'}
    var bfn = fn.bind(obj,100,200)  
    bfn()  // this 已经指向了obj
    
    
    1. 扩展
    function gn(){console.log(this)}
    gn.call('Hello') //会把Hello包装成一个对象
    gn.call(undefined) // 实际上是绑定到window上
    gn.call(null) //window
    gn.call(NaN) //  包装成一个Number对象
    
  2. new绑定 函数也是一个类 构造函数/构造器
    1. 通常情况下 首字母大写
        function Person(){
            // new 做了什么
            // 1. 在函数内部创建了一个对象
            // 2. 把函数内部的this绑定到对象上
            // 3. 函数执行
            // 4. 返回这个对象(new完后,肯定得到一个对象)            
        }
        // new一个类  得到一个对象  new 是一个运算符
        let p1 = new Person()
        console.log(p1) 
    

内置函数

  1. 定时器中的this是 window
setTimeout(function(){
    console.log(this) // window
},1000)

  1. 事件监听
<button id='btn'>click</button>
let btn = document.getElementById('btn')
btn.onclick = function(){
//监听器中的this表示事件源
    console,log(this)  //  <button id='btn'>click</button>
}
  1. 内置方法 forEach map

绑定优先级

默认绑定(独立函数) < 隐式绑定(对象.) < 显示绑定(call,apply,bind)
隐式绑定(对象.) < new绑定
bind绑定 < new绑定
new不能和call apply 比较 call apply函数已经执行 返回值不是一个对象

箭头函数

  1. 如果形参 小括号可以省略
  2. 如果函数体中 只有一条语句 {} / return 都可以省略
  3. 如果返回只有一个对象 如果省略return和{}对象的{}会当成函数的{}
  4. 如果没有形参 小括号不能省略
    let foo = (num1)=>{return{num*2}
    let foo = num1=>{return num*2} //省略小括号
    let foo = num1=> num*2 //省略return 和{}
    let foo = num1=>{return{a:666}} // 如果省略return和{}对象的{}会当成函数的{}
    let foo = num1 => ({a:666})

箭头函数中的this

  1. 箭头函数中的this 需要往上找一层
        let gn = function(){console.log(this);}
        let fn = ()=>console.log(this)
        let obj = {name:'boo'}
        gn.call(obj) //{name: 'boo'}
        fn.call(obj) //window  
        fn.call(undefined) //window
  1. IIFE中的this表示window 前面加分号避免代码执行时产生错误
    1. 立即执行函数前面都要写个分号 养成习惯
    ;(function(){console.log(this)})()  // window
    ;(()=>{console.log(this)})()  // window

练习题

var num = 10; 
var obj = {
    num: 20 
        // 返回一个函数作为obj的属性  
}
obj.fn = (function (num) { //传入实参 20
    this.num = num * 6; // 这里this指向window--IIFE中的this  此时全局中num变成60
    num++;   // 在自己EC中找  就是传入的实参变量20   num--21
    console.log(num);  // 打印21
    return function (n) {
        this.num += n; // 独立函数调用this指向window   num60 -- 65
        num++; //在自己EC中找,没找到去函数声明位置的父级EC中找 21--22
        console.log(num) //22
    }

})(obj.num)  //obj.num为20
var fn = obj.fn;  // 这里把对象的fn地址赋值给fn   没有调用
fn(5)  // 这里调用 独立函数调用  this指向window  
console.log(window.num); //65

16776875162897

posted @ 2023-03-02 00:31  callAjax  阅读(13)  评论(0编辑  收藏  举报