In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-01-17 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)06/03 Report--
JavaScript中this的绑定规则是怎样的,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。
对于 JavaScript 新手来说,this 是非常基础同时也难以理解的知识点。
比如下面的代码,this 指向就有三种方式。
function foo() { console.log(this.a); } var a = 1; var obj = { a: 2, foo: foo }; foo(); // 1 obj.foo(); // 2 foo.call({ a: 3 }); // 3
this 就是函数运行时所在的环境对象,它指向运行时所在的位置,而不是定义时的位置。
根据 this 绑定规则,分为下面四种:
默认绑定
隐式绑定
显式绑定
new 绑定
1. 默认绑定
默认情况下,this 指向全局对象。例如下面的代码。
var a = 2; console.log(this.a); // 2 // 在函数中 function foo() { console.log(this.a); } foo(); // 2 // 在回调函数中 function doFoo() { return function() { console.log(this.a); }; } doFoo()(); // 2
不过,函数在严格模式下,this 无法指向全局对象,因此this会绑定到undefined。
function foo() { "use strict"; console.log(this); } foo(); // undefined
2. 隐式绑定
当函数作为方法被调用,需考虑运行时上下文环境。
function foo() { console.log(this.a); } var obj = { a: 2, foo: foo }; obj.foo(); // 2
代码中,foo()前面添加了obj对象的修饰,因此,obj对象就是函数的上下文。
this 会绑定到这个对象上。
另外,需要注意下面三种情况,它们会出现绑定对象丢失,从而把this绑定到全局对象或undefined上。
情况一
这段代码中,虽然obj.foo()和bar()都指向同一函数,但执行结果并不一样。
可以理解为,bar()是一个不带任何修饰的函数调用,等价于直接调用foo(),因此应用了默认绑定。
function foo() { console.log(this.a); } var a = 3; var obj = { a: 2, foo: foo }; var bar = obj.foo; obj.foo(); // 2 bar(); // 3
情况二
另一种情况,发生在回调函数中。原理和上面的情况一样。
修改上面的代码,obj.foo作为参数传入doFoo()函数中,实际上,引用的是foo()函数本身,因此应用了默认绑定。
function foo() { console.log(this.a); } var a = 3; var obj = { a: 2, foo: foo }; function doFoo(fn) { return fn(); } doFoo(obj.foo); // 3
情况三
在一些流行的 JavaScript 库,进行事件处理操作时,回调函数的 this 可能会强制绑定到 DOM 元素上。
这种情况也值得注意。
3. 显式绑定
JavaScript 提供了call()、apply()和bind()方法,可以强制绑定函数的this对象。
function fn() { console.log(this.a); } fn.call({ a: 3 }); // 3
通过fn.call(obj),我们将函数运行时,this强制绑定到obj上。
call apply和bind的区别
call 和 apply 改变了函数的 this 上下文后,便执行该函数,而 bind 则是将该函数返回。
function fn() { console.log(this.a); } fn.call({ a: 3 }); // 3 fn.bind({ a: 4 })(); // 4
call和apply的区别
call 和 apply 的区别在于传入参数不同。
call 方法接收若干个参数列表。
apply 第一个参数和 call 一样,第二个参数接收一个包含多个参数的数组。
let arr = [2, 5, 9] console.log(Math.max.call(3, 2, 5, 9)) // 9 console.log(Math.max.call(3, arr)) // NaN console.log(Math.max.apply(3, arr)) // 9
4. new 绑定
如果使用 new 构造函数,在函数内部,this 指向新创建的对象。
function foo() { console.log(this); } new foo(); // foo {} foo(); // Window {...}
其他情况
需要忽略的this
若第三方库的某个函数使用了 this,默认绑定会把this指向全局对象,从而导致不可预测的后果。
一个安全的做法,就是使用显式绑定,将函数的this指向空对象。
function foo() { console.log(this); } // 创建空对象 var ø = Object.create(null); // 使用bind()进行柯里化(Curry) var bar = foo.bind(ø); bar(); // {}
这方法通常也用于对象初始化,以获得一个干净且高度可定制的对象。
箭头函数
箭头函数常用于回调函数中。
它会继承父级作用域 this 绑定的对象,等价于ES6之前self = this的书写方式。
const people = { name: "Merry", sayHi() { console.log(this.name) }, wait() { setTimeout(() => { console.log(this.name) }) } } people.sayHi() // Merry people.wait() // Merry
此外还有软绑定(softBind),用的不多,了解一下即可。
看完上述内容,你们掌握JavaScript中this的绑定规则是怎样的的方法了吗?如果还想学到更多技能或想了解更多相关内容,欢迎关注行业资讯频道,感谢各位的阅读!
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.