【JS】JavaScript 中 this 关键字

JavaScript 中 this 关键字

this 是什么

this 是一个关键字,能够在函数执行过程中访问运行环境,它的值根据函数的调用方式和上下文而变化,所以 this 是动态的,动态指向当前函数的运行环境。

this 是一个对象,当函数执行时产生的内部对象,this 指向只与函数的执行环节有关,与函数的声明无关。

this 是一个指针型变量,在 JavaScript 中没有指针的概念,但是this真实地指向当前调用对象,能够在函数内部访问和操作当前对象的属性和方法。

this 的绑定规则

1、默认绑定:

当函数独立调用时,即没有任何上下文对象时,默认绑定规则会将 this 绑定到全局对象(在浏览器中是 window 对象,在 Node.js 中是 global 对象)。

在严格模式下,默认绑定会将 this 绑定为 undefined

function foo() {
  console.log(this);
}

foo(); // 在浏览器中输出:window,在 Node.js 中输出:global
function foo(){
	console.log(this.a);
}

var a=2;
foo(); //在浏览器中输出:2,在 Node.js 中输出:undefined

2、隐式绑定:

当函数作为对象的方法调用时,会将 this 绑定到调用该方法的对象上。

function foo(){
	console.log(this); // {name: 'zhangsan', sayHello: ƒ}
	console.log(this.name); // zhangsan
}

var obj={
	name:'zhangsan',
    sayHello:foo //函数引用
}

obj.sayHello()

下面方式是同样的:

const obj = {
  name: 'zhangsan',
  sayHello: function() {
    console.log('Hello, ' + this.name);
  }
};

obj.sayHello(); // 输出:Hello, zhangsan

对象属性引用链只有在上一层或者说最后一层的在调用位置起作用,即只会指向上一个调用该函数的对象。

function foo(){
    console.log('指向的是:', this.name);
  }

var obj1={
    name:'obj1',
    foo:foo //隐式绑定的函数
}

var obj2={
    name:'obj2',
    obj1:obj1
}

obj2.obj1.foo();//指向的是:obj1  绑定对象是obj1,而不是obj2

3、显示绑定

通过 callapplybind 方法,可以显式地指定函数内部的 this 值。

  • call 方法接受一个指定的对象作为第一个参数,将该对象绑定到函数的 this。如果不传参数或传null、undefined 参数时都指向 Windows。
    语法:function.call(thisArg, arg1, arg2, …) 其中,thisArg是要绑定的对象,它将代替调用函数中的this关键字。后面的参数arg1、arg2等是可选的参数,它们被传递给调用的函数。
function foo() {
  console.log('Hello, ' + this.name);
}

var obj = {
  name: 'obj'
};

// 将 obj 绑定到函数 foo 上面
foo.call(obj); // 输出:Hello, obj
  • apply 方法与 call 类似,参数以数组形式接受。
    语法:function.apply(thisArg, [argsArray])。其中,thisArg是要绑定的对象,argsArray是一个数组类型的参数列表,它们被传递给调用的函数。
function foo(params) {
  console.log(params + ', ' + this.name);
}

var obj = {
  name: 'obj'
};

// 将 obj 绑定到函数 foo 上面,并向 foo 传递参数
foo.apply(obj,['Hello']); // 输出:Hello, obj

call和apply方法在函数调用时立即执行,而bind方法返回一个新的函数,需要手动调用。apply的参数需要以数组形式传入。

  • bind 方法会创建一个新函数,并将指定的对象绑定到新函数的 thisbind 方法不会立即调用函数,而是返回一个绑定了 this 的新函数。
function foo() {
  console.log('Hello, ' + this.name);
}

var obj = {
  name: 'obj'
};

// bind 会创建一个绑定 this 的新函数进行返回,但不会立即调用
var newFoo = foo.bind(obj);
newFoo(); // 输出:Hello, Bob

4、new 绑定:当使用 new 关键字调用函数作为构造函数来创建新对象时,this 会绑定到新创建的对象。

function Person(name) {
  this.name = name;
}

var zhangsan = new Person('Zhangsan');
console.log(zhangsan.name); // 输出:Zhangsan

5、箭头函数:箭头函数中的 this 继承自外部作用域,与函数的调用方式无关。

const obj = {
  name: 'Alice',
  sayHello: () => {
    console.log('Hello, ' + this.name);
  }
};

obj.sayHello(); // 输出:Hello, undefined

this 的指向

1、函数的普通调用

当函数直接调用时,this 指向调用它的那个对象,一般使用默认绑定。

function foo() {
  let a = "function name";
  console.log('a', a); // function name
  console.log('this.a', this.a); // window name
}

var a = "window name";
foo();//调用A(),当前运行环境是window,this指向window对象

2、构造函数

构造函数的 this 永远指向实例化对象

严格模式下,如果构造函数不加new调用,this 指向的是 undefined 如果给他赋值,则会报错

var Func = function () {
  this.a = "我是构造函数的属性";
  this.fun = function () {
    console.log(this);
  }
}
let myFunc = new Func();
myFunc.fun();//Func { a: '我是构造函数的属性', fun: [Function (anonymous)] }

3、箭头函数

箭头函数不会创建自己的 this ,所以它没有自己的 this,它只会从自己的作用域链的上一层继承 this。

如果外部函数是普通函数,this 的指向取决于外部函数的绑定类型,外部函数!=定义箭头函数的外部对象。

function foo() {
  var a = "function"
  setInterval(() => {
    console.log(this.a);//浏览器每个1秒打印window; node.js每隔一秒打印undefined
  }, 1000)
}
var a = "window"
foo();//箭头函数外部函数是foo; foo没有任何绑定,则使用默认绑定
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值