this指针的绑定规则
下面是对this指针绑定规则的整理,希望可以帮助到有需要的小伙伴。
(1)默认绑定
this被定义在某个函数体中
该函数被独立调用,没有作为任何一个对象的方法时
这个this就默认是指向全局对象的
如果这个全局对象存在,就去找全局对象的同名属性,返回该属性的值
如果没有可用的全局对象,还是会返回undefined
// 把this定义在某个函数体中
function fn(){
console.log(this.z);
}
// 独立调用该函数
fn(); // undefined
// 定义一个全局的变量
var z = 300;
// 由于该全局对象不可用,所以会返回 undefined
(2)隐式绑定
全局对象就是全局作用域的上下文对象。全局对象作用于整个全局作用域中。
在一个函数里定义内容,函数作用域或局部作用域。函数作为某个对象的方法时,这个对象就是整个函数作用域里的对象。
函数作为另一个对象的方法存在,该对象是函数作用域的上下文对象。
上下文对象:
一个带this指针的函数是不是另一个对象的方法,如果是,该对象就是带this指针的上下文对象,如果不是,该对象就不是带this指针的上下文对象。
或者说一个带this指针的函数被某个对象拥有或包含,该对象就是上下文对象。
隐式绑定:
如果调用位置有上下文对象,就是隐式绑定。
实例:
// 定义一个包含this指针的函数
function fn(){
console.log(this.h);
}
// 定义一个对象,该对象的方法是包含this指针的函数
var obj = {
h : 400,
f : fn
};
// 调用对象的方法
obj.f(); // 400
// obj对象就是fn()函数的上下文对象。
调用位置会使用obj上下文对象来引用fn()函数,函数fn()被调用时obj对象就“拥有”或“包含”它。
隐式丢失是最常见的this绑定问题,指的就是被隐式绑定的函数会丢失绑定对象。
如果隐式绑定的了某个上下文对象,由于定义了一个和this调用的属性或方法同名的全局的属性或方法,定义一个该函数的别名,调用别名,该this对象就会指向全局对象。
实例:
var a = "global"; // a是全局对象的属性
function foo(){
console.log(this.a);
}
var obj = {
a : 2,
fo : foo // 对象的fo()方法指向foo()函数
};
// obj.foo(); // 就是隐式绑定,输出2
// 定义一个全局变量,并被赋值为对象obj的fo()方法 // 注意:bar是foo函数的别名,引用的是foo函数本身
var bar = obj.fo;
// 将bar作为一个函数进行调用
bar(); // 就是单纯的函数调用foo 相当于调用单独foo()函数 默认foo函数的对象是全局对象 输出的是undefined
(3)显示绑定
显示绑定可以解决隐式丢失的问题
利用apply()、call()方法让this固定指向一个对象,将该对象作为一个参数传进去,传给apply()或call()
实例:
var a = "global"; // a是全局对象的属性
function foo(){
console.log(this.a);
}
var obj = {
a : 2,
fo : foo // 对象的fo()方法指向foo()函数
};
// obj.foo(); // 就是隐式绑定,输出2
// 定义一个全局变量,并被赋值为对象obj的fo()方法 // 注意:bar是foo函数的别名,引用的是foo函数本身
var bar = obj.fo;
// 将bar作为一个函数进行调用
// bar(); // 就是单纯的函数调用foo 相当于调用单独foo()函数 默认foo函数的对象是全局对象 输出的是undefined
// 解决隐式丢失的显示绑定
// 1.调用apply()函数
// bar.apply(obj); // 2
// 2.调用call()函数
bar.call(obj); // 2
(5)new绑定
new绑定就是构造函数创建对象时的new,new哪个对象,this就指向哪个对象。
// 创建一个构造函数
function Hero(name) {
this.name = name;
}
// 定义对象
var hero1 = new Hero('张无忌'); // this指向hero11
console.log(hero1); // Hero { name: '张无忌' }
var hero2 = new Hero('周芷若'); // this指向hero2
console.log(hero2); // Hero { name: '周芷若' }
4种绑定总结:
-
默认指向全局对象
-
隐式绑定看上下文对象
-
显示绑定用call()或apply()明确指出this指向的是哪个对象
-
new绑定看new之后创建的对象是谁,this就指向谁
(如果有错误,希望大佬指正,万分感谢!)