8人参与 • 2025-04-24 • Javascript
this对象:解析器在每次调用函数时,都会向函数内部转递一个隐含的参数,这个参数就是this,this指向的是一个对象,这个对象我们称为函数执行的上下文对象,根据函数调用方式的不同,this会指向不同的对象
在全局环境中(不在任何函数或对象内部),this指向全局对象(在浏览器环境中是window,在node.js中是global)
console.log(this === window); // 在浏览器中输出 true
当一个函数被直接调用时,this在非严格模式下指向全局对象(window),在严格模式下指向undefined
js严格模式:javascript在语法和行为上存在一些模糊的特性,可能导致一些不易察觉的错误,为提高代码的质量和可维护性,js引入了严格模式,通过启用一些额外的规则,强制执行更严格的语法和行为。在严格模式下代码中的潜在问题将被捕获并抛出错误,有助于提前发现和修复潜在bug。
function regularfunction() { console.log(this); } regularfunction(); // 非严格模式下指向 window,严格模式下为 undefined // 演示严格模式下的情况 (function () { "use strict"; regularfunction(); })();
当函数作为对象的方法被调用时,this指向调用该方法的对象
var person = { name: "john", sayname: function () { console.log(this.name); } }; person.sayname(); // 输出 "john",这里的 this 指向 person 对象
使用new关键字(实例化)调用函数时,该函数被当作构造函数(类),this会指向新创建的对象实例
function person(name) { this.name = name; this.sayhello = function () { console.log("hello, i'm " + this.name); }; } var john = new person("john"); john.sayhello(); // 输出 "hello, i'm john",这里 this 指向 john 实例
构造函数怎么执行创建对象的过程:
在构造函数中,创建对象和返回对象都给我们隐藏了,使用同一个构造函数创建的对象,我们称为一类对象,也将一个构造函数称为一个类。我们将通过一个构造函数创建的对象,称为是该类的实例。
在dom事件处理函数中,this通常指向触发事件的元素。
<button id="mybutton">click me</button> <script> var button = document.getelementbyid("mybutton"); button.onclick = function () { console.log(this); // 点击按钮时,这里的 this 指向按钮元素 //打印 :<button id="mybutton">click me</button> }; </script>
箭头函数没有自己的this,它的this继承自外层作用域的this
// 普通函数 function outerfunction() { this.name = "outer"; var innerfunction = function () { console.log(this.name); }; innerfunction(); } // 箭头函数 function outerfunctionwitharrow() { this.name = "outer with arrow"; var innerfunction = () => { console.log(this.name); }; innerfunction(); } new outerfunction(); // 输出 undefined,因为 innerfunction 中的 this 指向全局对象,全局对象没有 name 属性 new outerfunctionwitharrow(); // 输出 "outer with arrow",箭头函数的 this 继承自 outerfunctionwitharrow 的 this
由于箭头函数的this来自于继承,箭头函数无法使用以下三种方法改变this指向
call
方法是附加在函数调用后面使用,可以忽略函数本身的 this 指向var obj = { name: 'jack' } function fn(a, b) { console.log(this) console.log(a) console.log(b) } fn(1, 2) fn.call(obj, 1, 2)
fn(1,2)
的时候,函数内部的 this 指向 window(函数被直接调用)fn.call(obj, 1, 2)
的时候,函数内部的 this 就指向了 obj 这个对象apply
方法是附加在函数调用后面使用,可以忽略函数本身的 this 指向var obj = { name: 'jack' } function fn(a, b) { console.log(this) console.log(a) console.log(b) } fn(1, 2) fn.apply(obj, [1, 2])
fn(1,2)
的时候,函数内部的 this 指向 window(函数被直接调用)fn.call(obj, 1, 2)
的时候,函数内部的 this 就指向了 obj 这个对象bind
方法是附加在函数调用后面使用,可以忽略函数本身的 this 指向var obj = { name: 'jack' } function fn(a, b) { console.log(this) console.log(a) console.log(b) } fn(1, 2) var newfn = fn.bind(obj) newfn(1, 2)
fn(1, 2)
的时候 this 指向 windownewfn(1, 2)
的时候执行的是一个和 fn 一摸一样的函数,只不过里面的 this 指向改成了 obj这里我们补充一下在回调函数运用中this指向(也是容易混淆的知识点)
如果回调函数是一个对象的方法,并且是以对象方法的方式传递进去的,那么 this 通常会指向该对象。
var myobject = { value: 10, callbackfunction: function () { console.log(this.value); } }; [1,2,3].foreach(() => { myobject.callbackfunction() }); //输出三个10
在这个例子中,foreach 是数组的方法,myobject.callbackfunction 作为回调函数传递给 foreach。当 foreach 调用这个回调函数时,this 仍然指向 myobject,因为这个函数本质上还是 myobject 的一个方法。
箭头函数没有自己的 this,它会继承外层作用域的 this(依据词法作用域规则)。
function outerfunction() { this.name = "outer"; var array = [1, 2, 3]; array.foreach(() => { console.log(this.name); //打印三次outer }); } new outerfunction();
根据上面两个例子,这里我们介绍一下普通函数和箭头函数在确定this指向时的一些区别:
1、普通函数
普通函数在函数定义时会确定函数的作用域,但不会明确函数中this的指向。普通函数中this的指向是在函数被调用时被确定(指向调用者或者全局对象)
2、箭头函数
箭头函数由于其本身不会生成this,其this继承自外层作用域。箭头函数在定义时不仅会确定作用域,而且会捕获外层作用域的this作为自身的this,箭头函数的this在定义时就已经确定,在其后的函数调用时,无论调用箭头函数的是谁它的this指向都不会发生改变。
以上面这个例子为例:
箭头函数定义在 outerfunction 这个函数内部,注意不是定义在 foreach 方法内。具体可以了解一下函数传参的步骤,这里箭头函数是先在 outerfunction 这个函数内部定义,之后才作为参数传给 foreach 方法。箭头函数继承了 outerfunction 函数的this,并在之后被 foreach 方法调用时不会发生改变。
当普通函数作为回调函数,并且这个普通函数是被一个全局函数(如 settimeout、setinterval)或者在全局作用域中独立调用的函数(没有通过对象来调用)调用时,在非严格模式下,this 通常会指向全局对象。
//被一个全局函数调用 settimeout(function () { console.log(this); }, 1000);
//在全局作用域中独立调用 function outer(){ inner() } function inner(){ console.log(this); } outer()
this指向:1、普通函数:谁调用函数,this就指向谁,没有调用者就指向全局对象window
2、箭头函数:箭头函数不会创建this,它的this继承自上层作用域中的this
//回调函数中错误使用this var person = { name: "eve", greetlater: function () { settimeout(function () { console.log(this.name); // 此处的function为普通函数,作为settimeout的参数this指向全局对象 }, 1000); } }; person.greetlater();
此处的function为普通函数,被一个全局函数调用,其this指向全局对象 window 。
要想输出 eve ,将此处的普通函数改为箭头函数即可。
var person = { name: "eve", greetlater: function () { settimeout( ()=> { console.log(this.name); // 输出eve }, 1000); } }; person.greetlater();
//在嵌套函数中混淆 this 指向 var outer = { name: "outer object", innerfunction: function () { var inner = { name: "inner object", nestedfunction: function () { console.log(this.name); // 这里 this 指向 inner,而不是 outer } }; inner.nestedfunction(); } }; outer.innerfunction();
nestedfunction 是作为 inner 对象的方法被调用,this指向 inner 对象(根据普通函数 this 指向的规则,当函数作为对象的方法被调用时,this 会指向调用该函数的对象。)
想要访问到 outer 对象的 name 属性,可以使用以下两种方法:
1、保存外层 this 的引用
var outer = { name: "outer object", innerfunction: function () { var self = this; var inner = { name: "inner object", nestedfunction: function () { console.log(self.name); // 现在可以访问到 outer 的 name 属性,输出 "outer object" } }; inner.nestedfunction(); } }; outer.innerfunction();
在方法的开头先把 this 保存到一个变量中(通常命名为 self 或 that 等),然后在 inner 对象中使用这个保存的变量来访问 outer 对象的属性。
2、使用箭头函数
var outer = { name: "outer object", innerfunction: function () { var inner = { name: "inner object", nestedfunction: () => { console.log(this.name); // 输出 "outer object" } }; inner.nestedfunction(); } }; outer.innerfunction();
将 nestedfunction 改为箭头函数,因为箭头函数会继承外层作用域的 this,在这里外层作用域是 outer.innerfunction(),其 this 指向 outer 对象,所以箭头函数里的 this 也能指向 outer 对象。
到此这篇关于javascript中this(普通函数、箭头函数、 函数运用)的文章就介绍到这了,更多相关js中this普通函数、箭头函数、回调函数运用内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!
您想发表意见!!点此发布评论
版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。
发表评论