你不了解的JS笔记 - 第二部分 - this

this是在运行时进行绑定的,并不是在编写时绑定,它的上下文取决于函数调用时的各种条件

this的绑定和函数声明的位置没有任何关系,只取决于函数的调用方式

当一个函数被调用时,会创建一个活动记录(也称为执行上下文),这个记录会包含函数在哪里被调用,函数的调用方式,传入的参数等信息,this就是这个记录的一个属性,会在函数执行的过程中用到


调用位置就是函数在代码中被调用的位置,在当前正在执行的函数的前一个调用中


默认绑定:函数直接使用不带任何修饰的函数引用进行调用(独立函数调用),只能使用默认绑定,无法应用其他规则,非严格模式下,默认绑定绑定到全局对象,在严格模式下绑定到undefined

隐式绑定:当函数引用有上下文对象时,隐式绑定规则会把函数调用中的this绑定到这个上下文对象

对象属性引用链中只有上一层或者说最后一层在调用位置中起作用

显示绑定:所有函数都可以使用call()和apply()方法,它们的第一个参数是一个对象,接着在调用函数时将其绑定到this

如果传入一个原始值来当做this的绑定对象,这个原始值会被转换成它的对象形式,这通常被称为装箱

硬绑定:一种显式的强制绑定

function foo(){
    console.log(this.a)
}
var obj = {
    a:2
}
var bar = function(){
    foo.call(obj)
}

可以创建一个包裹函数,负责接收参数并返回值

var bar = function(){
    return foo.apply(obj,arguments)
}

另一种是创建一个可以重复使用的辅助函数

function bind(fn,obj){
    return function(){
        return fn.apply(obj,arguments)
    }
}
var bar = bind(foo,obj)
bar(3)

ES5提供了内置的方法Function.prototype.bind,返回一个硬编码的新函数,把指定的参数设置为this的上下文并调用原始函数

JS许多内置函数或第三方库函数都提供了一个可选的参数,通常被称为上下文,其作用和bind一样,确保回调函数使用指定的this,实际上都是通过call或apply实现了显示绑定

new绑定:在JS中,构造函数只是一些使用new操作符时被调用的函数,它们并不会属于某个类,也不会实例化一个类,只是被new操作符调用的普通函数而已

所有函数都可以用new调用,这种函数调用被称为构造函数调用

使用new来调用函数,或者说发生构造函数调用时,会自动执行下面的操作:

  • 创建一个全新的对象
  • 这个新对象会被执行[[Prototype]]连接
  • 这个新对象会绑定到函数调用的this
  • 如果函数没有返回其他对象,那么new表达式中的函数调用会自动返回这个新对象

bind()方法会判断硬绑定函数是否被new调用,如果是的话就会使用新创建的this替换硬绑定的this。

在new中使用硬绑定函数主要目的是预先设置函数的一些参数,这样在使用new进行初始化时就可以只传入其余的参数

根据优先级判断this:

  • 函数是否在new中调用?如果是的话this绑定的是新创建的对象
  • 函数是否通过call,apply或者硬绑定调用?如果是的话,this绑定的是指定的对象
  • 函数是否在某个上下文对象中调用?如果是的话,this绑定的是那个上下文对象
  • 如果都不是的话,使用默认绑定,如果在严格模式下,就绑定到undefined,否则绑定到全局对象

如果null或undefined作为this的绑定对象传入call、apply或者bind,这些值在调用时会被忽略,实际应用的是默认绑定规则

apply可以用来展开数组,并当做参数传入一个函数;bind可以对参数进行柯里化,预先设置一些参数

Object.create(null)可以创建一个空对象,并且不会创建Object.prototype这个委托,比{}更空

忽略this绑定时传入空对象可以避免对全局对象产生影响

有可能会创建一个函数的间接引用,在这种情况下,调用这个函数会应用默认绑定规则


箭头函数不使用this的四种标准规则,而是根据外层作用域来决定this

箭头函数的绑定无法被修改,箭头函数可以像bind一样确保函数的this绑定到指定的对象,用常见的词法作用域取代了传统的this机制

posted @ 2025-06-04 21:46  永生辉皇  阅读(9)  评论(0)    收藏  举报