1. JavaScript中为什么要有this机制?
#include <iostream>
using namespace std;
class Bar{
public:
char* myName;
Bar(){
myName = "冰淇淋";
}
void printName(){
cout<< myName <<endl;
}
} bar;
char* myName = "抹茶";
int main() {
bar.printName();
return 0;
}
在这段 C++ 代码中,调用了 bar 对象中的 printName 方法,最后打印出来的值就是 bar 对象的内部变量 myName 值——“冰淇淋”,而并不是最外面定义变量 myName 的值——“抹茶”,所以调用对象内部的方法中,使用的是对象内部的属性,是一个非常普遍的需求。但是 JavaScript 的作用域机制并不支持这一点,基于这个需求,JavaScript 又搞出来另外一套 this 机制。
2. this绑定的规则
this绑定规则主要有四种,如下所示
1.默认绑定
this没有指明绑定的对象,默认指向全局对象(客户端 JavaScript 中,全局对象就是 Window 对象)
function foo(){
console.log('foo函数:'+this.a);
}
var a=2;
foo();
console.log('全局对象:'+window.a);
2.隐式绑定
当函数引用有上下文对象时,隐式绑定规则会把函数调用中的this绑定到这个上下文对象。
对象属性引用链中只有上一层或者说最后一层在调用位置中起作用 使用对象来调用其内部的方法,其this指向的是对象本身。
function foo(){
console.log(this.a);
}
var obj2={
a:42,
foo:foo
};
var obj1={
a:2,
obj2:obj2
};
obj1.obj2.foo();
3.显示绑定
使用call(...),apply(...),bind(...)方法,直接指定this的绑定对象,称之为显式绑定
function foo(){
console.log(this.a);
}
var obj2={
a:42,
foo:foo
};
var obj1={
a:2,
obj2:obj2
};
var a=100;
foo.call(obj2);
foo.call(obj1);
foo.call(window);
4. new绑定
JavaScript 中,构造函数只是一些使用new 操作符被调用的函数 包括内置对象函数在内的所有函数都可以用new来调用,这种函数调用被称为构造函数调用
使用new来调用函数,或者说发生构造函数调用时,会自动执行下面的操作。
- 创建(或者说构造)一个全新的对象
- 这个新对象会被执行[[Prototype]]连接
- 这个新对象会绑定到函数调用的this
- 如果函数没有返回其他对象,那么new表达式中的函数调用会自动返回这个对象
function foo(a){
this.a = a;
this.b = b;
}
var b = 12;
var bar = new foo(2);
console.log(bar.a);
console.log(bar.b);
3. 优先级
new绑定 > 显式绑定 > 隐式绑定 > 默认绑定