JavaScript的this四种绑定方式
最近在学习JavaScript的过程中,发现了this
这个东东,so,今天咱们扒拉扒拉这到底咋用。
this呢,有四种绑定方式:默认绑定,隐式绑定,显式绑定和new绑定。
先不管这四种绑定方式是啥,一句话是核心:函数中的this总是指向调用他的对象。
下面我们来看第一种绑定方式:
1.默认绑定
当一个函数没有明确的调用对象的时候,也就是单纯作为独立函数调用的时候,将对函数的this使用默认绑定:绑定到全局的window对象。简单说就是一句话:凡是函数作为独立函数调用,都和直接在全局环境中调用一样。(即默认绑定window)
来,咱们举例䁖一眼:
var a = 2
function fn() {
console.log(this.a)
}
fn() //2
很多小伙伴发现自己在vscode中直接看结果输出结果是undefined,原因是你在vscode中函数的执行环境 Node.js,在浏览器 JavaScript 中,通常 window 是全局对象, 而 Node.js 中的全局对象是 global,所以,在html中的<script>
标签之内可以看到在浏览器中看到输出结果。
2.隐式绑定
当函数被一个对象“包含”的时候,我们称函数的this被隐式绑定到这个对象里面。
1.在隐式绑定中,如果函数调用位置是在一串对象属性链中,this绑定的是最内层的对象。
2.当函数引用有上下文对象时,隐式绑定规则会把函数调用中的this绑定到这个上下文对象。
还是直接上代码更直接:
var a = 2
function fn() {
console.log(this.a)
}
var o = {
a:3,
fn:fn
}
o.fn() //3
fn() //2
还是上面那句话:函数中的this总是指向调用他的对象。 没毛病!!!
但是,我们看下面的问题出在了哪儿呢??
var a = 2
function fn() {
console.log(this.a)
}
var o = {
a: 3,
fn: fn
}
var func = o.fn
func() //2
我们把o的fn方法赋给func,然后执行func(),然后输出结果是2,这是为啥嘞??
原因是,函数赋值的过程无法把fn所绑定的this也传递过去。这就是this绑定丢失的问题(隐式丢失问题)。
3.显式绑定(call,apply和bind方法)
首先,call,apply基本类似,只是传参不同,第一个参数都是对象,前者对象后面传多个参数,后者对象后面传递一个数组,
fn.call(obj, arg1, arg2, arg3, ...);
fn.apply(obj, [arg1, arg2, arg3, ...])
我们就只介绍call方法:
var a = 2
function fn() {
console.log(this.a)
}
var o = {
a: 3
}
fn.call(o,a) //3
fn.bind(o,a)() //3
call和bind的区别是:在绑定this到对象参数的同时:
1.call将立即执行该函数
2.bind不执行函数,只返回一个可供执行的函数
在隐式绑定下:函数和只是暂时属于“包含对象“。
在显式绑定下:函数将一直属于“包含对象“
4.NEW绑定
执行new操作的时候,将创建一个新的对象,并且将构造函数的this指向所创建的新对象。
function fn(a) {
this.a = a
}
var a1 = new fn(1);
var a2 = new fn(2);
var a3 = new fn(3);
var a4 = new fn(4);
console.log(a1.a); // 输出1
console.log(a2.a); // 输出2
console.log(a3.a); // 输出3
console.log(a4.a); // 输出4
this的绑定规则
new > 显示绑定 > 隐式绑定 > 默认绑定