js中的this详解

this的指向一直都是js中的一大难点,接下来将会从以下方面对this的指向进行总
结,包含一些面试题。

一、this的默认绑定

function foo() {
  console.log(this)   //window
}
foo()
function test1() {
  console.log(this)   //window
  test2()
}
function test2() {
  console.log(this)   //window
  test3()
}
function test3() {
  console.log(this)   //window
}
test1()
function foo(func) {
  func()
}
var obj = {
  name:"why",
  bar: function() {
    console.log(this)   //window
  }
}
foo(obj.bar)

二、隐式绑定

function foo() {
  console.log(this)
}
var obj = {
  name: "why",
  foo: foo
}
obj.foo()  //obj
function foo() {
  console.log(this)   //obj1
}
var obj1 = {
  name: "obj1",
  foo: foo
}
var obj2 = {
  name: "obj2",
  obj1: obj1
}
obj2.obj1.foo()
function foo() {
  console.log(this)   //window
}
var obj1 = {
  name: "obj1",
  foo: foo
}
var bar = obj1.foo
bar()

三、显示绑定:可以通过call,bind,apply

//apply,call指明绑定对象
function foo() {
  console.log(this)
}
foo.call(window)  //window
foo.call({name:"dl"})   //{name:dl}
foo.call(123)   //Number{123}
//如果我们希望总是绑定到一个对象上,则可以使用bind
function foo() {
  console.log(this)   //obj
}
var obj = {
  name: "Why"
}
var bar = foo.bind(obj)
bar()

四、内置函数绑定

//setTimeout
setTimeout(function() {
  console.log(this)  //window
}, 1000)

//点击事件触发
const app = document.querySelector("#app")
app.onclick= function() {
  console.log(this) //app
}

//forEach函数
const arr = ['name','set','age']
arr.forEach(item => {
  console.log(this)  //window
}, {name:"ss"})

const arr = ['name', 'set', 'age']
arr.forEach(function () {
  console.log(this)     //{ name:"ss" }
}, {
  name: "ss"
})

五、new绑定

对于构造函数来说:每一次new实例化对象都会执行以下操作
1、创建一个全新的对象
2、将全新的对象的原型指向该函数的原型对象上
3、新对象绑定this
4、将this返回
function Person(name) {
  console.log(this) //Person {}
  this.name = name //Person {name:"why"}
}
var p = new Person("why")
console.log(p)

六、规则优先级顺序

new > bind > 显示 > 隐式 > 默认
因为new不允许和call和bind一起使用。

七、特殊规则

//当使用显示绑定来绑定undefined或者null时,该显示绑定会自动被忽略
function foo() {
  console.log(this)
}
var obj = {
  name: "why"
}
foo.call(obj)   //obj
foo.call(null)  //window
foo.call(undefined)  //window

var bar = foo.bind(null)
bar()  //window

//当使用赋值时,同样也使用默认绑定规则
function foo() {
  console.log(this)
}
var obj1 = {
  name: "obj1",
  foo: foo
}
var obj2 = {
  name: "obj2"
}
obj1.foo(); //obj1
(obj2.foo = obj1.foo)() //window
//这个可以这样想:左边obj1.foo拿到的就是函数,赋值给右边还是原来的函数,所以就是函数直接执行

//ES6中的this指向
var obj = {
  data:[],
  getData: function() {
    setTimeout(() => {
      console.log(this)   //obj对象
    })
  }
}
obj.getData()

//二
var obj = {
  data:[],
  getData: () => {
    setTimeout(() => {
      console.log(this)  //window
    })
  }
}
obj.getData()

八、this指向面试题

var name = "window"
var person = {
  name: "person",
  sayName: function () {
    console.log(this.name)
  }
}
function sayName() {
  var sss = person.sayName;
  sss();
  person.sayName();
  (person.sayName)();
  (b = person.sayName)();
}
sayName()
//输出
//  window
//  person
//  person   //这个加个括号和不加括号一样
//  window
var name = "window"
var person1 = {
  name: "person1",
  foo1: function () {
    console.log(this.name)
  },
  foo2: () => console.log(this.name),
  foo3: function () {
    return function () {
      console.log(this.name)
    }
  },
  foo4: function () {
    return () => {
      console.log(this.name)
    }
  }
}
var person2 = {
  name: "person2"
}
person1.foo1()    //person1
person1.foo1.call(person2)  //person2

person1.foo2()  //window
person1.foo2.call(person2)  //window

person1.foo3()()   //window
person1.foo3.call(person2)()    //window
person1.foo3().call(person2)    //person2

person1.foo4()()  //person1
person1.foo4.call(person2)()  //person2
person1.foo4().call(person2)  //person1
var name = "window"
var person1 = {
  name: "person1",
  foo1: function () {
    console.log(this.name)
  },
  foo2: () => console.log(this.name),
  foo3: function () {
    return function () {
      console.log(this.name)
    }
  },
  foo4: function () {
    return () => {
      console.log(this.name)
    }
  }
}
var person2 = {
  name: "person2"
}
person1.foo1()    //person1
person1.foo1.call(person2)  //person2

person1.foo2()  //window
person1.foo2.call(person2)  //window 这里的this绑定对于箭头函数来说没什么用

person1.foo3()()   //window
person1.foo3.call(person2)()    //window
person1.foo3().call(person2)    //person2

person1.foo4()()  //person1
person1.foo4.call(person2)()  //person2
person1.foo4().call(person2)  //person1
var name = "window"

function Person(name) {
  this.name = name
  this.foo1 = function () {
    console.log(this.name)
  }
  this.foo2 = () => console.log(this.name)
  this.foo3 = function () {
    return function () {
      console.log(this.name)
    }
  }
  this.foo4 = function () {
    return () => {
      console.log(this.name)
    }
  }
}
var person1 = new Person("person1")
var person2 = new Person("person2")

person1.foo1()    //person1
person1.foo1.call(person2)  //person2

person1.foo2()  //person1
person1.foo2.call(person2) //person1

person1.foo3()()  //window
person1.foo3.call(person2)()   //window
person1.foo3().call(person2)  //person2

person1.foo4()()  //person1
person1.foo4.call(person2)()  //person2
person1.foo4().call(person2) //person1
var name = "window"

function Person(name) {
  this.name = name
  this.obj = {
    name: "obj",
    foo1: function () {
      return function () {
        console.log(this.name)
      }
    },
    foo2: function () {
      return () => {
        console.log(this.name)
      }
    }
  }
}
var person1 = new Person("person1")
var person2 = new Person("person2")

person1.obj.foo1()()   //window
person1.obj.foo1.call(person2)()  //window
person1.obj.foo1().call(person2)  //person2

person1.obj.foo2()()  //obj
person1.obj.foo2.call(person2)()  //person2
person1.obj.foo2().call(person2)  //obj
  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值