我是靠谱客的博主 复杂背包,这篇文章主要介绍javaScript中this的指向,现在分享给大家,希望可以做个参考。

javaScript中this的指向

非箭头函数

this => 调用其所在函数对象,而且距离谁近指向谁(常规对象,原型链,getter & setter都适用);

构造函数

this => 被新创建的对象

DOM事件

this => 触发事件的元素

内联事件

bind/call & apply

全局环境

在全局环境下,this 始终指向全局对象(window), 无论是否严格模式;

复制代码
1
2
3
4
5
6
console.log(this.document === document); // true // 在浏览器中,全局对象为 window 对象: console.log(this === window); // true this.a = 37; console.log(window.a); // 37

函数上下文调用

函数直接调用

普通函数内部this分两种情况 严格模式和非严格模式

非严格模式下 this指向 window 对象

复制代码
1
2
3
4
5
function f1() { return this } console.log(f1 === window); // true

严格模式下 this为 undefind

复制代码
1
2
3
4
5
6
function f2() { 'use strict' // 严格模式 return this } console.log(f2() === undefind); // true

Object 中的this

对象内部方法的this指向调用这些方法的对象

  1. 定义函数的位置和this没有关系,只和调用函数的对象有关。
  2. 多层嵌套的对象,内部函数调用的this指向调用函数最近的对象(window也是对象,其内部对象调用方法的this指向内部对象,非window对象)。
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
var Obj = { name: 'Mary', age: 20, getName: function () { return this.name } } console.log(Obj.getName()); // Mary this 指向 Obj(最近的) var f3 = Obj.getName; console.log(f3()); // undefind this 指向 f3(最近的) 非 Obj function Age() { return this.age } Obj.getAge = Age; console.log(Obj.getAge()); // 20 this 指向 Obj(最近的) Obj.prop = { getAge: Age, age: 30 } console.log(Obj.prop.getAge()); // 30 this 指向 Obj.prop(最近的) 非 Obj

原型链中this

原型链中方法的this同样指向调用它的对象

复制代码
1
2
3
4
5
6
7
8
9
10
var Obj = { Todo: function() { return this.a + this.b } } var P = Object.create(Obj); P.a = 2; P.b = 3; console.log(P.Todo()); // 5 this 指向 P 调用方法的对象(最近的)

由此可见 P 中没有 Todo 方法,但是执行 P.Todo 时,会查找P的原型链,找到 Todo 函数并执行,但这与内部this指向P没有任何关系,
和调用函数的对象有关系。

getter & setter

同上所述

构造函数中的 this

构造函数的 this 与新创建的对象绑定

注:当构造器返回的默认值是 this 引用的一个对象时,可手动设置返回其他对象。
如果返回值不是一个对象,则返回 this。

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
function C1() { this.name = 'Mary'; } var P1 = new C1(); console.log(P1.name); // Mary 返回值不是对象 而是this function C2() { this.name = 'Mary'; return { name: 'Tom' } } var P2 = new C2(); console.log(P2.name); // Tom 返回值是一个对象 可手动更改 this.name = 'Mary' 被忽略

call && apply

当函数通过 Function 原型中继承的 call() & apply() 方法时,其函数内部的 this 可绑定到 call() & apply() 方法指定的第一个对象上,
如果第一个参数不是 Object,JavaScript内部会尝试将其转换成 Object 然后指向它。

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
function Add(c, d) { console.log(this); return this.a + this.b + c + d } var obj = {a: 5, b: 9}; Add.call(obj, 6, 8); // {a: 5, b: 9} Add.apply(obj, [7, 9]); // {a: 5, b: 9} function Cost() { console.log(this) } Cost.call(7); // Number {[[PrimitiveValue]]: 5} Cost('222'); // STring {[[PrimitiveValue]]: '222'} Cost.apply(7); // Number {[[PrimitiveValue]]: 5} Cost.apply([7]); // [7]

bind 方法

Function.prototype.bind

通过 bind 方法绑定后,函数被永远绑定在第一个参数对象上,被一直调用。

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
function todo() { return this.name } var Foo = todo.bind({name: 'Mary'}); console.log(Foo()); // Mary var Bar = { name: 'Tom', age: 20, getName: todo } console.log(Bar.getName()); // Tom 同 Object 中的 this

setTimeout & setInterval

延时函数内部 this 指向 window 对象,可以使用 bind 改变其 this 指向。

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
function Person1() { this.age = '20'; setTimeout(function() { console.log(this) },1000) } var P1 = new Person1(); // 1s 后输出 window 对象 function Person2(age) { this.age = age; setTimeout(function() { console.log(this) },1000).bind(this) } var P2 = new Person2(20); // 1s 后输出 P2 (新生成的 Person2 对象)

箭头函数中的 this

方法内部箭头函数,非方法方式调用

注:箭头函数没有定义this绑定,它会捕获其所在(即定义的位置)上下文的this值, 作为自己的this值。

  1. call() & apply() & bind() 只是传入参数,对 this 没有影响。
  2. 考虑到 this 是词法层面上的,严格模式中与 this 相关的规则都将被忽略。(可以忽略是否在严格模式下的影响)

因为箭头函数可以捕获其所在上下文的this值,所以

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
function Person1() { this.age = 10; setTimeout(() => { console.log(this) },1000) } var P1 = new Person1(); // 1s 后输出 P1 (新生成的 Person1 对象) function Person2() { this.age = '20'; setTimeout(function() { console.log(this) },1000) } var P2 = new Person1(); // 1s 后输出 window 对象

使用箭头函数,this 指向上下文的 this, 而普通函数则指向 window 对象.

** Object 中的箭头函数 **

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
var People = { firstName: 'Mary', getName: function(lastName) { var f1 = str => `${this.firstName} ${str}`; return f1(lastName) }, getFullName: function isFull(lastName) { var f2 = str => `${this.firstName} ${str}`; var auther = { firstName: 'Tom' }; return f2.call(auther, lastName) } } console.log(People.getName('Mr')); // Mary Mr this 指向 People console.log(People.getFullName('Mr')); // Mary Mr this 仍然指向 People,没有因为 call 而改变。

严格模式和非严格模式对比

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
var f1 = () => { 'use strict'; return this } var f2 = () => { return this } console.log(f1()); // window 对象 console.log(f2()); // window 对象 console.log(f1() === f2()); // true 因为都是 window 对象

箭头函数作为方法调用

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
var obj = { i: 10, b: () => { console.log(this.i, this) }, c: function () { console.log(this.i, this) } } obj.b(); // undefind window 对象 (注:箭头函数没有定义this绑定) obj.c(); // 10 对象 obj (注:函数最近的对象) var fun = obj.c; fun(); // undefind window 对象 (注:调用最近的对象 fun 非 obj)

DOM 中的 this

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
case1: <button onclick="console.log('1:', this)">1</button> // 1: <button οnclick="console.log('1:', this)">1</button> (注:this 指向该元素) case2: html <button onclick="handleClick2()">2</button> js function handleClick2(){ // 非严格模式 console.log('2:', this) // 2: window } case3: html <button onclick="handleClick3()">3</button> js function handleClick3(){ "use strict"; // 严格模式 console.log('3:', this) // 3: undefind } case4: html // error 格式 此写法是不允许的 <button onclick="() => handleClick4()">4</button>

最后

以上就是复杂背包最近收集整理的关于javaScript中this的指向的全部内容,更多相关javaScript中this内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(76)

评论列表共有 0 条评论

立即
投稿
返回
顶部