JS中的this

本文深入探讨了JavaScript中this关键字的工作原理及其在不同上下文中的行为表现。解释了this如何随着函数调用方式的变化而变化,并介绍了Function.call和Function.apply方法如何帮助明确this的指向。

在此,我假设您已经在运用Javascript中的类概念,假设您还了解OOP中的this.

还是习惯从实例来分析:

 
var someObject = {};
function someMethod(){
 alert((this==window)+','+(this==someObject));
}
someObject.someMethod = someMethod;
someMethod();//true,false
someObject.someMethod();//false,true

 

上面的代码是定义了一个function和一个对象,并指定对象的某个属性为那个function;

在执行方法时我们知道,可以通过someObject.someMethod()这样调用,也可以通过someMethod()这样直接调用;
归根结底,这两种调用方式都能找到相应内存中的function-someMethod(有名方法),并执行。
但由于this在Javascript中的特殊性,这两种调用方式的输出却截然不同,前者返回false,true,而后者返回true,false,why?

网上有很多描述,我在此以我的理解作一个直白的描述,在需要JS处理机区分this时,方法由谁调用,则this表示谁。(之后会说明不需要JS处理机区分的情况)
someObject.someMethod()调用者为someObject,所以this==someObject返回true;
someMethod ()呢?对window有所理解的人应该知道,Javascript页面级的作用域为window,即缺省有名对象都相当于window的一个属性,如定义var a;相当于指定window.a属性,定义function b同样相当于指定window.b属性。所以someMethod()的调用相当于window.someMethod()调用,调用者为window,所以this==window返回true;

若是只有这样,可能大家还是比较容易理解,在Javascript中还存在两个特殊方法,Function.call和Function.apply。
这两个方法的调用者为someFunction,参数分别为:
call(oCaller,arg1,arg2,...)
apply(oCaller,[arg1,agr2,...])
这两个方法可以显式的告诉JS处理机,执行someFunction中的this对象为我的第一个参数oCaller,这也就是我之前提到的不需要JS处理机区分的情况;
有兴趣的同学可以试运行以下的实例:

 
var someObject = {};
var someObject2 = {};
function someMethod(){
 alert((this==window)+','+(this==someObject)+','+(this==someObject2));
}
someObject.someMethod = someMethod;
someMethod();//true,false,false
someObject.someMethod();//false,true,false
someMethod.apply(someObject);//or call//false,true,false
someMethod.apply(someObject2);//false,false,true

还有一种特殊情况,new操作符处理函数,new操作符会创建一个新对象,将this指向这个新对象,然后进行操作,所以其中的this不表示任何已知句柄的对象,而是一个新的匿名对象,通过赋值语句可以指定给某个变量或者对象属性上,在此不再多作蛰述,试运行以下示例;

 
var someObject = {};
function ClassA(){
 alert((this==window)+','+(this==someObject));
 this.someAttr = 'someAttr';
}
someObject = new ClassA();//false,false
alert(someObject.someAttr);//someAttr

JavaScript中,`this` 关键字是一个非常重要且灵活的概念,它代表函数运行时自动生成的一个内部对象,只能在函数内部使用,其指向会根据函数的调用方式不同而发生变化 [^2]。 ### 全局作用域下的 `this` 在全局作用域下,`this` 关键字会指向顶层对象,在浏览器环境中就是 `window` 对象 [^4]。 ```javascript var name = 'keith'; function person() { return this.name; } console.log(person()); // 'keith' ``` ### 函数中使用 `this` 在函数中使用 `this` 属于全局使用,代表全局对象,可通过 `window` 对象来访问 [^3]。 ```javascript function test() { this.x = 1; console.log(this); } test(); // 调用者是 window console.log(x); // 相当于定义在全局对象上的属性 console.log(this.x); ``` ### 对象中使用 `this` 在对象的方法中,`this` 指向调用该方法的对象。 ```javascript const obj = { name: 'John', sayName: function() { console.log(this.name); } }; obj.sayName(); // 'John' ``` ### 构造函数中使用 `this` 在构造函数中,`this` 指向新创建的对象。 ```javascript function Person(name) { this.name = name; } const person1 = new Person('Alice'); console.log(person1.name); // 'Alice' ``` ### 箭头函数中的 `this` 箭头函数没有自己的 `this`,它的 `this` 继承自外层函数。 ```javascript const obj = { name: 'Bob', sayName: () => { console.log(this.name); } }; obj.sayName(); // 这里的 this 指向全局对象,输出为空或 undefined ``` ### 改变 `this` 指向的方法 可以使用 `call()`、`apply()` 和 `bind()` 方法来改变 `this` 的指向。 ```javascript function greet() { console.log(`Hello, ${this.name}`); } const person = { name: 'Charlie' }; greet.call(person); // 'Hello, Charlie' ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值