![e7ec2c7926b411149a2554cc94f3d377.png](https://img-blog.csdnimg.cn/img_convert/e7ec2c7926b411149a2554cc94f3d377.png)
this的不同指向
this 关键字是一个非常重要的语法点。毫不夸张地说,不理解它的含义,大部分开发任务都无法完成。 记住一点: this 不管在什么地方使用:它永远指向一个对象。 下面是一个实际的例子。
var person = {
name: "张三",
describe: function() {
console.log("姓名:" + this.name);
}
};
person.describe();
输出:
// "姓名:张三"
上面代码中, this.name 表示 name 属性所在的那个对象。由于 this.name 在 describe 方法中调用,而 describe 方法所在的当前对象是 person ,因此 this 指向 person ,this.name 就是 person.name 。
由于对象的属性可以赋给另一个对象,所以属性所在的当前对象是可变的,即 this 的指向是可变的。
var A = {
name: "张三",
describe: function() {
console.log("姓名:" + this.name);
}
};
var B = {
name: "李四"
};
B.describe = A.describe;
B.describe()
输出:
// "姓名:李四"
上面代码中, A.describe 属性被赋给 B ,于是 B.describe 就表示 describe 方法所在的当前对象 B ,所以 this.name 就指向 B.name 。
稍稍重构这个例子, this 的动态指向就能看得更清楚。
function f() {
console.log("姓名:" + this.name);
}
var A = {
name: "张三",
describe: f
};
var B = {
name: "李四",
describe: f
};
A.describe();
B.describe();
输出:
// "姓名:张三"
// "姓名:李四"
上面代码中,函数 f 内部使用了 this 关键字,随着 f 所在的对象不同, this 的指向也不同。
只要函数被赋给另一个变量, this 的指向就会变。
var A = {
name: '张三',
describe: function() {
console.log('姓名:' + this.name);
}
};
var name = '李四';
var f = A.describe;
f() // "姓名:李四"
输出:
// "姓名:李四"
上面代码中, A.describe 被赋值给变量 f ,的内部 this 就会指向 f 运行时所在的对象(本例是顶层对象)。
JavaScript语言之中,一切皆对象,运行环境也是对象,所以函数都是在某个对象下运行的, this 就是函数 运行时所在的对象(环境)。这本来并不会让我们糊涂,但是JavaScript支持运行环境动态切换,也就是 说, this 的指向是动态的,没有办法事先确定到底指向哪个对象,这才是最初初学者感到困惑的地方。
this使用场合
(1)全局环境
全局环境使用 this ,它指的就是顶层对象 window 。
this === window // true
function f() {
console.log(this === window);
}
f() // true
输出:
//true
(2)构造函数
构造函数中的 this ,指的是实例对象。
function F() {
this.hello = function() {
console.log('Hello' + this.name);
}
}
var f1 = new F();
f1.name = '张三';
f1.hello();
var f2 = new F();
f2.name = '刘能';
f2.hello();
输出:
//"Hello张三"
//"Hello刘能"
(3)对象的方法
方法在哪个对象下,this就指向哪个对象。
var o1 = {
s1: '123',
f1: function() {
console.log(this.s1)
}
}
var o2 = {
s1: '456',
f1: o1.f1
}
o2.f1();
输出:
//"456"
使用this时的注意事项
(1) 避免包含多层this
var o = {
f1: function() {
console.log(this);
var f2 = function() {
console.log(this);
}
f2();
}
}
o.f1()
输出:
// Object
// Window
如果要在内层函数中使用外层的this指向,一般的做法是:
var o = {
f1: function() {
console.log(this);
var that = this;
var f2 = function() {
console.log(that);
}
f2();
}
}
o.f1()
输出:
// Object
// Object
(2)不在循环数组中使用this
var ar = ['a', 'b', 'c'];
ar.forEach(function(v, k, ar) {
console.log(this[k])
})
输出:
//undefined *3
this 的动态切换,固然为JavaScript创造了巨大的灵活性,但也使得编程变得困难和模糊。 有时,需要把 this 固定下来,避免出现意想不到的情况;JavaScript提供了 call , apply , bind 这三个方法, 来切换/固定 this 的指向。
this三种固定指向方法:
call()方法:
var lisi = {
names: '李四'
};
var zs = {
names: '张三'
};
function f(age) {
console.log(this.names);
console.log(age);
}
f(23); //undefined
f.call(zs, 32); //张三
输出:
//undefined
//23
//张三
//32
call方法使用的语法规则
函数名称.call(obj,arg1,arg2...argN);
参数说明:
obj:函数内this要指向的对象,
arg1,arg2...argN ;参数列表,参数与参数之间使用一个逗号隔开
apply()方法
var lisi = {
name: '李四'
};
var zs = {
name: '张三'
};
function f(age, sex) {
console.log(this.name + age + sex);
}
f.apply(zs, [23, '岁']);
输出:
//"张三23岁"
函数名称.apply(obj,[arg1,arg2...,argN])
参数说明:
obj :this要指向的对象
[arg1,arg2...argN] :参数列表,但是要求格式为数组
bind()方法
bind 方法用于将创建一个新的函数,且将新函数中的 this 绑定到具体的某个对象上
function foo() {
console.log(this.a);
}
var obj2 = {
a: 2,
};
// 创建新函数,并将新函数中的this固定的指向obj2对象;
var new_foo = foo.bind(obj2);
new_foo(); //2
foo(); //undefined
输出:
//2
//undefined
以上是我对this指向和this固定指向的理解,分享给大家,希望可以在为this指向烦恼的同学有所帮助。