当前位置:首页 > Web开发 > 正文

#p#分页标题#e# (想要深入理解 [call apply bind this硬绑定

2024-03-31 Web开发

js 的 this 绑定问题,让大都新手懵逼,部分老手感受恶心,这是因为this的绑定 ‘难以捉摸’,堕落的时候还往往不知道为什么,相当反逻辑。
让我们考虑下面代码:

var people = { name : "海洋饼干", getName : function(){ console.log(this.name); } }; window.onload = function(){ xxx.onclick = people.getName; };

在平时搬砖时对照常见的this绑定问题,大家可能也写给或者遇到过,当xxx.onclick触发时,输出什么呢 ?

为了便利测试,我将代码简化:

var people = { Name: "海洋饼干", getName : function(){ console.log(this.Name); } }; var bar = people.getName; bar(); // undefined

通过这个小例子带大家感应熏染一下this恶心的处所,我最开始遇到这个问题的时候也是一脸懵逼,因为代码里的this在创建时指向非常明显啊,指向本身 people 东西,但是实际上指向 window 东西,这就是我顿时要和大家说的 this 绑定法则

1 . this

什么是this ?在讨论this绑定前,我们得先搞清楚this代表什么。

this是JavaScript的关键字之一。它是 东西 自动生成的一个内部东西,只能在 东西 内部使用。跟着函数使用场合的差别,this的值会产生变革。

this指向什么,完全取决于 什么处所以什么方法挪用,而不是 创建时。(对照多人误解的处所)(它非常语义化,this在英文中的含义就是 这,这个 ,但这其实起到了必然的误导感化,因为this并不是一成不乱的,并不必然一直指向当前 这个

2 . this 绑定法则

掌握了下面介绍的4种绑定的法则,那么你只要看到函数挪用就可以判断 this 的指向了

2 .1 默认绑定

考虑下面代码:

function foo(){ var a = 1 ; console.log(this.a); // 10 } var a = 10; foo();

这种就是范例的默认绑定,我们看看foo挪用的位置,”光杆司令“,像 这种直接使用而不带任何修饰的函数挪用 ,就 默认且只能 应用 默认绑定。

那默认绑定到哪呢,一般是window上,严格模式下 是undefined。

2 .2 隐性绑定

代码措辞:

function foo(){ console.log(this.a); } var obj = { a : 10, foo : foo } foo(); // ? obj.foo(); // ?

答案 : undefined 10

foo()的这个写法熟悉吗,就是我们刚刚写的默认绑定,等价于打印window.a,故输出undefined ,
下面obj.foo()这种大家应该经常写,这其实就是我们顿时要讨论的 隐性绑定

函数foo执行的时候有了上下文东西,即 obj。这种情况下,函数里的this默认绑定为上下文东西,等价于打印obj.a,故输出10 。

如果是链性的关系,好比 xx.yy.obj.foo();, 上下文取函数的直接上级,即紧挨着的阿谁,或者说东西链的最后一个。

2 .3 显性绑定 2 .3 .1 隐性绑定的限制

在我们刚刚的 隐性绑定中有一个致命的限制,就是上下文必需包罗我们的函数 ,例:var obj = { foo : foo },如果上下文不包罗我们的函数用隐性绑定明显是要堕落的,不成能每个东西都要加这个函数 ,那样的话扩展,维护性太差了,我们接下来聊的就是直接 给函数强制性绑定this

2 .3 .2 call apply bind

这里我们就要用到 js 给我们供给的函数 call 和 apply,它们的感化都是转变函数的this指向第一个参数都是 设置this东西

两个函数的区别:

call从第二个参数开始所有的参数都是 原函数的参数。

apply只接受两个参数,且第二个参数必需是数组,这个数组代表原函数的参数列表。

例如:

function foo(a,b){ console.log(a+b); } foo.call(null,‘海洋‘,‘饼干‘); // 海洋饼干 这里this指向不重要就写null了 foo.apply(null, [‘海洋‘,‘饼干‘] ); // 海洋饼干

除了 call,apply函数以外,还有一个转变this的函数 bind ,它和call,apply都差别。

bind只有一个函数,且不会立刻执行,只是将一个值绑定到函数的this上,并将绑定好的函数返回。例:

function foo(){ console.log(this.a); } var obj = { a : 10 }; foo = foo.bind(obj); foo(); // 10

(bind函数非常出格,下次和大家一起讨论它的源码)

2 .3 .2 显性绑定

开始正题,上代码,就用上面隐性绑定的例子 :

function foo(){ console.log(this.a); } var obj = { a : 10 //去失里面的foo } foo.call(obj); // 10

我们将隐性绑定例子中的 上下文东西 里的函数去失了,显然此刻不能用 上下文.函数 这种形式来挪用函数,大家看代码里的显性绑定代码foo.call(obj),看起来很怪,和我们之前所了解的函数挪用不一样。

其实call 是 foo 上的一个函数,在转变this指向的同时执行这个函数。

温馨提示: 本文由Jm博客推荐,转载请保留链接: https://www.jmwww.net/file/web/31414.html