关于javascript:js5种this绑定简析

36次阅读

共计 2393 个字符,预计需要花费 6 分钟才能阅读完成。

this 绑定 /this 指向

  1. 默认绑定 – window
  2. 隐式绑定 – context
  3. 显示绑定 – call、apply、bind
  4. new 绑定 – 新对象
  5. 箭头函数绑定 – 下层作用域

1. 默认绑定

function fn1() {
    let a = 1;
    let fn2 = function () {console.log(this);
        console.log(this.a);
    }
    fn2();
    return fn2
}
var a = 2;
fn1() //window 2
fn1()() //window 2 window 2

无论函数在哪申明或调用,调用时函数前 无对象,this 最终都指向window

2. 隐式绑定

function fn() {console.log(this.name);
}
let obj1 = {
    name: "boj1",
    fn
}
let obj2 = {
    name: "obj2",
    obj1
}
obj2.obj1.fn() //obj1

函数调用前 有对象 时,this就近 指向上下文对象

若未寻找到属性返回undefined,不会在 obj2 上找

隐式失落

  1. 参数传递
  2. 变量赋值

参数传递

let name = "window"
function fn() {console.log(this.name);
}
let obj1 = {
    name: "obj1",
    fn
}
let obj2 = {
    name: "obj2",
    obj1
}
function func(param) {param()
}
func(obj2.obj1.fn) //window

fn 作为参数在 func 中调用,this 指向失落,默认指向 window

变量赋值

let name = "window"
function fn() {console.log(this.name);
}
let obj1 = {
    name: "obj1",
    fn
}
let obj2 = {
    name: "obj2",
    obj1
}
let func = obj2.obj1.fn
func();//window

将 fn 赋给 func,func 的调用 this 默认指向 window

3. 显示绑定

  1. bind
  2. call
  3. apply

bind

let name = "window"
function fn() {console.log(this.name);
}
let obj1 = {
    name: "obj1",
    fn
}
let obj2 = {
    name: "obj2",
    obj1
}
function func1(param) {param()
}
func1(obj1.fn.bind(obj2)) //obj2
let func2 = obj1.fn.bind(obj2)
func2() //obj2

绑定 :fn.bind(obj) 将 fn 绑定在 obj 上并返回一个函数,不论是参数传递还是变量赋值都 不会呈现绑定失落 的状况
参数 :bind 第一个参数为绑定的对象,前面的能够追加参数作为函数的实参,传递一个 数组 时不会主动解构
优先级 :显示绑定 > 隐式绑定 > 默认绑定
硬绑定 :绑定后不可应用 bind、call、apply 再 从新绑定

call

let name = "window"
function fn() {
    let name = this.name
    return function fn1() {console.log(name, this.name);
    }
}
let obj1 = {
    name: "obj1",
    fn
}
let obj2 = {
    name: "obj2",
    obj1
}
function func1(param) {param()
}
func1(obj1.fn.call(obj2)) //obj2 window
let func2 = obj1.fn.call(obj2)
func2() //obj2 window
func2.call(obj1) //obj2 obj1

绑定 :call 绑定不同与 bind 的返回一个绑定的函数,而是 立刻执行 这个函数
参数 :与 bind 雷同,this 指向第一个参数,后续参数作为实参,数组不主动解构
软绑定 :本次调用时为绑定,下次执行还须要再次绑定
闭包 :在绑定时只绑定最外层作用域,父函数返回的函数在调用时为 默认绑定,当对其绑定时,其 this 会被绑定,不影响外层作用域

apply

let arr = ["param1", "param2"]
let name = "window"
function fn(...arr) {console.log(this.name, arr[0], arr[1]);
}
let obj1 = {
    name: "obj1",
    fn
}
let obj2 = {name: "obj2",}
obj1.fn.apply(obj2, arr)//obj2 param1 param2

绑定 :apply 与 call 雷同,会 立刻执行 被绑定的函数,同样也是软绑定
参数 :第一个参数也是绑定的对象,前面与 call 不同,apply 传递的数组 会解构 赋给函数的的形参

4.new 绑定

function fn(name) {this.name = name}
let obj = new fn("obj")
console.log(obj.name); //obj
console.log(new fn("new"));// {name:new}

用 new 去调用函数,会将该函数作为一个构造函数,把该函数的 this 指向一个新创建的对象,返回该对象

5. 箭头函数

能够与 call 中的例子比照

let name = "window"
function fn() {
    let name = this.name
    return () => {console.log(name, this.name);
    }
}
let obj1 = {name: "obj1",}
let obj2 = {name: "obj2",}
let func2 = fn.call(obj2)
func2() // obj2 obj2
func2.call(obj1) // obj2 obj2
let func1 = fn.call(obj1)
func1() //obj1 obj1

箭头函数没有本人的 this,它会应用上一层作用域的 this
对箭头函数的绑定是没有成果的,批改指向须要批改下层作用域的 this

正文完
 0