欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 财经 > 产业 > javascript 中 函数this的指向

javascript 中 函数this的指向

2025/6/7 6:51:22 来源:https://blog.csdn.net/qq_44136028/article/details/148425114  浏览:    关键词:javascript 中 函数this的指向
函数this的指向

在全局环境中,this指向

  • 浏览器中window
  • node中global
function foo(){console.log(this) // // 浏览器中:Window 对象 ,NODE中:global对象
}
foo()
"use strict";.....
// 严格模式下 this 为 undefined:
this的指向,跟函数所处的位置无关,跟函数的调用方式有关

function foo() {console.log(this)
}// 1.直接调用这个函数
foo() // this指向全局对象(在浏览器中是 Window 对象)// 2.创建一个对象, 对象中的函数指向foo
var obj = {name: 'SUMU',foo: foo
}obj.foo() // this指向obj对象// 3.apply调用
foo.apply("abc") // this指向"abc"
默认绑定
//案例1:
function foo() {console.log(this) // this 指向window对象
}foo()// 2.案例二:
function foo1() {console.log(this) // this 指向window对象
}function foo2() {console.log(this) // this 指向window对象foo1()
}function foo3() {console.log(this) // this 指向window对象foo2()
}foo3()// 3.案例三:
var obj = {foo: function() {console.log(this) // this 指向window对象}
}var bar = obj.foo
bar() // 4.案例四:
function foo() {console.log(this) // this 指向window对象
}
var obj = {foo: foo
}var bar = obj.foo
bar() // 5.案例五:
function foo() {function bar() {console.log(this)}return bar
}var fn = foo()
fn() // this 指向window对象var obj = {eating: fn
}obj.eating() // 隐式绑定 {name: 'sumu', eating: ƒ}
隐式绑定
function foo() {console.log(this) // this 指向obj对象 }
var obj = {foo: foo 
}
obj.foo() // this 指向obj对象// 2.案例二:
var obj = {name: "alive",eating: function() {console.log(this,'eating')console.log(this.name + "在吃东西")},running: function() {console.log(obj.name + "在跑步")}
}obj.eating() // this 指向obj对象 // 输出结果为: alive在吃东西obj.running() // this 指向obj对象 输出结果为: alive在跑步var fn = obj.eating
fn() // this 指向window对象 输出结果为: 在吃东西// 3.案例三:
var obj1 = {name: "obj1",foo: function() {console.log(this)}
}var obj2 = {name: "obj2",bar: obj1.foo
}obj2.bar() // this 指向obj2对象 输出结果为: obj2
显式绑定 (call/apply/bind)
function foo() {console.log("函数被调用了", this)
}
var obj = {name: "obj"
}// call/apply是可以指定this的绑定对象
foo.call(obj) // this 指向obj对象
foo.apply(obj) // this 指向obj对象
foo.apply("aaaa") // this 指向"aaaa"对象// 2.call和apply有什么区别?
// 传递的参数不一样
// call传递的是参数列表
// apply传递的是数组function sum(num1, num2, num3) {console.log(num1 + num2 + num3, this)
}sum.call("call", 20, 30, 40)
sum.apply("apply", [20, 30, 40])// 3.bind
// bind是返回一个新的函数 ,永久绑定 this 并返回新函数
var fn = sum.bind("bind", 10, 20, 30)
fn() // this 指向"bind"对象 输出结果为: 60 bind
fn() // this 指向"bind"对象 输出结果为: 60 bind
new绑定

使用 new 调用构造函数时,this 指向新创建的对象:

function Person(name, age) {console.log(this) //Person {}this.name = namethis.age = age
}var p1 = new Person("sumu", 18)
console.log(p1.name, p1.age)var p2 = new Person("kobe", 30)
console.log(p2.name, p2.age)
DOM 事件处理函数中的 this

在 DOM 事件处理函数中,this 指向触发事件的元素:

const boxDiv = document.querySelector('.box')
boxDiv.onclick = function() {console.log(this) //this 指向boxDiv对象 <button> 元素
}boxDiv.addEventListener('click', function() {console.log(this) // this 指向boxDiv对象 <button> 元素
})
箭头函数中的 this( 看定义时的外层作用域 )

箭头函数 没有自己的 this,其 this 继承自外层作用域

  • 箭头函数 this 的核心规则​
  • 继承外层作用域的 this
    箭头函数没有自身的 this,它会​​捕获定义时所在作用域的 this 值​​,且​​无法被修改​​(即使使用 call、apply、bind)
const obj = {name: "Alice",show: () => console.log(this.name)  // this 指向全局对象(非严格模式)
};
obj.show(); // 输出 undefined(全局 name 未定义)
  • ​​与调用方式无关
    无论箭头函数如何被调用(作为方法、回调等),其 this 始终由​​定义时的词法作用域​​决定
const obj = {method() {setTimeout(() => console.log(this), 100); // this 指向 obj}
};
obj.method(); // 输出 obj 对象
  • 全局作用域中的表现​
    在全局作用域定义的箭头函数,this 指向全局对象(浏览器中为 window,Node.js 中为 global)
// 案例1:
// 1.测试箭头函数中this指向
var name = "sumu"var foo = () => {console.log(this)
}foo() // this 指向window对象var obj = {foo: foo}obj.foo() // this 指向window对象foo.call("abc") // this 指向window对象// 案例2:
const obj = {name: 'sumu',foo: function() {console.log(this) // this 指向obj对象 {name: 'sumu', foo: ƒ}const bar = () => {console.log(this) // this 指向obj对象 {name: 'sumu', foo: ƒ}}bar()}
}
obj.foo()// 案例3:
var obj = {data: [],getData: function() {// 发送网络请求, 将结果放到上面data属性中// 在箭头函数之前的解决方案// var _this = this// setTimeout(function() {//   var result = ["abc", "cba", "nba"]//   _this.data = result// }, 2000);// 箭头函数之后setTimeout(() => {console.log(this,'obj') // this 指向obj对象 {data: Array(0), getData: ƒ}var result = ["abc", "cba", "nba"]this.data = result}, 2000);}
}obj.getData()
特性箭头函数普通函数
this 绑定静态绑定(定义时确定)动态绑定(调用时确定)
能否修改 this❌ 不可用 call/apply/bind 修改✅ 可通过 call/apply/bind 修改
构造函数❌ 不可用 new 调用(报错)✅ 可用 new 创建实例
arguments 对象❌ 不存在✅ 存在
其他
// 3.数组.forEach/map/filter/find
var names = ["abc", "cba", "nba"]
names.forEach(function(item) {console.log(item, this) // this 指向String->abc
}, "abc")
names.map(function(item) {console.log(item, this) // this 指向String->cba
}, "cba")setTimeout(function() {console.log(this) // window
}, 2000)
优先级
// 一.显示绑定 > 隐式绑定 
var obj = {name: "obj",foo: function() {console.log(this)}
}obj.foo() // this 指向obj对象 {name:'obj', foo: ƒ}// 1.call/apply的显示绑定高于隐式绑定obj.foo.apply('abc') // this 指向"abc"obj.foo.call('abc') // this 指向"abc"// 2.bind的优先级高于隐式绑定var bar = obj.foo.bind("cba")bar() // this 指向"cba"// 3.更明显的比较
function foo() {console.log(this)
}var obj = {name: "obj",foo: foo.bind("aaa")
}obj.foo() // this 指向"aaa"//二. new的优先级高于隐式绑定
var f = new obj.foo() // this指向foo// 结论: new关键字不能和apply/call一起来使用// new的优先级高于bind
function foo() {console.log(this,'xxx') 
}var bar = foo.bind("aaa")var obj = new bar() // //  new绑定 > 显示绑定(apply/call/bind) > 隐式绑定(obj.foo()) > 默认绑定(独立函数调用)//三.特殊绑定-忽略显示绑定
function foo() {console.log(this)
}foo.apply("abc")
foo.apply({})// apply/call/bind: 当传入null/undefined时, 自动将this绑定成全局对象
foo.apply(null) // this指向window
foo.apply(undefined) // this指向windowvar bar = foo.bind(null)
bar() // this指向window
  • this面试题一
var name = "window";var person = {name: "person",sayName: function () {console.log(this.name);}
};function sayName() {var sss = person.sayName;sss(); // window: 独立函数调用person.sayName(); // person: 隐式调用(person.sayName)(); // person: 隐式调用(b = person.sayName)(); // window: 赋值表达式(独立函数调用)
}sayName();
  • this面试题二
var name = 'window'var person1 = {name: 'person1',foo1: function () {console.log(this.name)},foo2: () => console.log(this.name),foo3: function () {return function () {console.log(this.name)}},foo4: function () {return () => {console.log(this.name)}}
}var person2 = { name: 'person2' }person1.foo1(); // person1(隐式绑定)
person1.foo1.call(person2); // person2(显示绑定优先级大于隐式绑定)
person1.foo2(); // window(不绑定作用域,上层作用域是全局)
person1.foo2.call(person2); // window
person1.foo3()(); // window(独立函数调用)
person1.foo3.call(person2)(); // window(独立函数调用)
person1.foo3().call(person2); // person2(最终调用返回函数式, 使用的是显示绑定)
person1.foo4()(); // person1(箭头函数不绑定this, 上层作用域this是person1)
person1.foo4.call(person2)(); // person2(上层作用域被显示的绑定了一个person2)
person1.foo4().call(person2); // person1(上层找到person1)
  • this面试题三
var name = 'window'function Person (name) {this.name = namethis.foo1 = function () {console.log(this.name)},this.foo2 = () => console.log(this.name),this.foo3 = function () {return function () {console.log(this.name)}},this.foo4 = function () {return () => {console.log(this.name)}}
}var person1 = new Person('person1')
var person2 = new Person('person2')person1.foo1() // person1
person1.foo1.call(person2) // person2(显示高于隐式绑定)person1.foo2() // person1 (上层作用域中的this是person1)
person1.foo2.call(person2) // person1 (上层作用域中的this是person1)person1.foo3()() // window(独立函数调用)
person1.foo3.call(person2)() // window
person1.foo3().call(person2) // person2person1.foo4()() // person1
person1.foo4.call(person2)() // person2
person1.foo4().call(person2) // person1
  • this 面试题四

var name = 'window'
function Person (name) {this.name = namethis.obj = {name: 'obj',foo1: function () {return function () {console.log(this.name)}},foo2: function () {return () => {console.log(this.name)}}}
}var person1 = new Person('person1')
var person2 = new Person('person2')person1.obj.foo1()() // window
person1.obj.foo1.call(person2)() // window
person1.obj.foo1().call(person2) // person2person1.obj.foo2()() // obj
person1.obj.foo2.call(person2)() // person2
person1.obj.foo2().call(person2) // obj
调用方式this指向示例
全局/普通函数调用非严格模式:全局对象(window,严格模式:undefined)function fn() { console.log(this); };fn(); // window(非严格模式)
对象方法调用调用该方法的对象obj.fn(); 中 this 指向 obj
构造函数调用new 创建的新对象实例const p = new Person(); 中构造函数内 this 指向 p
显式绑定call/apply/bind 的第一个参数fn.call(obj); 中 this 指向 obj
箭头函数继承定义时外层作用域的 thisconst foo = () => { console.log(this); } // 继承外层 this

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词