Javascript this指向

本文详细解释了JavaScript中this关键字的绑定规则,包括默认绑定(全局或对象属性)、隐式绑定(对象上下文)、显示绑定(call/apply/bind)以及new绑定。还探讨了原生DOM事件中this的指向差异。
摘要由CSDN通过智能技术生成

this是所有函数在被调用时,定义在函数的作用域中。是根据函数调用的方式决定的,并不是由书写的位置决定的。

1.默认绑定

直接调用,即是:不做this更改和作为对象属性调用时。this是全局对象,浏览器中则是Window对象。

function baz(){
  console.log(this); // Window
  bar();
}
function bar(){
  console.log(this); // Window
  foo();
}
function foo(){
  console.log(this); // Window
}
baz();

上述代码在浏览器执行是打印都是Window,即使bar和foo函数是在baz和bar函数中被调用的,但是他与书写位置无关,都是指向window。
注意:函数内容在严格模式执行时this是undefined:

function baz(){
  'use strict'
  console.dir(this); // undefined
}
baz();

注意:函数在严格模式调用时是正常的:

function baz(){
  'use strict'
  // 在严格模式下执行,undefined
  console.dir(this); // undefined
  // 在严格模式下被调用Ok
  bar();
}
function bar(){
  console.dir(this); // Window
}
baz();

隐式绑定

作为对象的属性被调用时。则this会被绑定到该对象上。

// 函数属性
function baz(){
  console.dir(this); // Window
}
baz.bar = function(){
  console.dir(this);  // f baz()
}
baz();
baz.bar();

// 对象属性
let obj = {
  a: 1,
  b:function() {
    console.dir(this) // Object {a: 1, b: function}
    console.log(this.a) // 1
  }
}
obj.b();

注意:只绑定上一层(最后一层)

let obj1 = {
  a: 1,
  b:function() {
    console.dir(this) // Object {a: 1, b: function}
    console.log(this.a) // 1
  }
}
let obj2 = {
  a: 2,
  obj1,
}
obj2.obj1.b();

注意:隐式丢失,当使用默认隐式绑定的函数被赋值给其他变量或者作为参数传递时。

// 赋值给其他变量
var a = 2
let obj1 = {
  a: 1,
  b:function() {
    console.dir(this) // Window
    console.log(this.a) // 2
  }
}
let myB = obj1.b
myB()

// 作为参数传递
var a = 2
let obj1 = {
  a: 1,
  b:function() {
    console.dir(this) // Window
    console.log(this.a) // 2
  }
}

function foo(fn) {
  fn()
}

foo(obj1.b)

显示绑定

通过call、apply、bind改变this指向。

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

foo.call(obj)

// apply
var a = 1
var obj = {
	a: 2
}
function foo() {
	console.log(this) // Object { a: 2}
	console.log(this.a) // 2
}

foo.apply(obj)

new 绑定

当使用new来调用函数,返回一个对象时:
1.创建一个全新的对象
2.这个对象的内部[[prototype]]特性被赋值为构造函数的prototype属性
3.构造函数内部的this被赋值为这个新对象
4.执行内部代码(给新对象添加属性)
5.如果返回非空对象,则返回该对象;否则,返回刚创建的新对象

function Foo() {
  this.a = 1
}

let bar = new Foo()
console.log(bar.a) // 1

原生dom事件中的this

绑定原生事件可以有三种:

// 第一种
<input id="input" type="text" onchange="change()" />
function change() {}

// 第二种
var myInput = document.querySelector('#input')
document.getElementById("input").onchange = function() {}

// 第三种
var myInput = document.querySelector('#input')
myInput.addEventListener('change', function() {})

它们三种情况下this指向有何不同?
1.先看第一种:

var myInput = document.querySelector('#input')
function change() {
  console.dir(this,'this')
  console.dir(myInput,'myInput')
  // 此时不能用this
  document.getElementById("span").innerHTML = myInput.value
}

在这里插入图片描述
this是window。虽然函数赋值给了input对象的onchange属性,但this不是input对象。可见在事件触发时,至少不是通过input.onchange()调用的。
2.第二种:

var myInput = document.querySelector('#input')
myInput.onchange = function() {
   console.dir(this)
   console.dir(myInput)
   // 此时可以通过this取得value值
   document.getElementById("span").innerHTML = this.value
 }

在这里插入图片描述
this是input。同时函数赋值给了input对象的onchange属性。
第三种情况:

var myInput = document.querySelector('#input')
myInput.addEventListener('change', function() {
  console.dir(this)
  console.dir(myInput)
  document.getElementById('span').innerHTML = this.value
})

在这里插入图片描述
this是input。但函数并没有赋值给input对象的onchange对象,所以通过input.onchange()调用函数是行不通的。
在这里插入图片描述
那是如何把this绑定到input对象上的呢?**哈哈不知道!**需要注意在函数使用this或者操作dom对象本身时,这些不同情况的差异就好了。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值