this是什么?
JavaScript中所有的函数都有属性,就如对象有属性一样。函数执行时会获取this
属性的值,此时this
就是一个变量,储存着调用该函数的对象的值。
this
这个引用总是指代对象并储存着它的值(只能指代一个对象),一般都在函数或者对象方法里使用,但是也能用在函数外的全局作用域里。需要注意的是,如果在函数里使用严格模式,全局函数里this的值就是undefined
。而在匿名函数里则不会绑定任何对象。
this调用情景
在JavaScript中,只有当函数被调用,this才会被赋值生效。
var f = function () {
console.log(this.x);
}
var x = 1;
var obj = {
f: f,
x: 2,
};
// 单独执行
f() // 1
// obj 环境执行
obj.f() // 2
上面代码中,函数f
在全局
环境执行,f函数是通过window.f()调用的,所以该函数结果是1,而obj.f函数是通过obj调用的,所以结果是2。
$ ("div").click (function (event) {
console.log (this);
});
上面是一个jq的方法,这里的调用形式可以理解为$("div")就是obj对象,click函数就是$("#div")中的一个对象,所以该方法中的this指向$("#div")。
多层调用时
function foo() {
console.log( this.a );
}
var a = 2;
var obj1 = {
a: 4,
foo: foo
};
var obj2 = {
a: 3,
obj1: obj1
};
obj2.obj1.foo(); //4
上面代码中foo是在obj1对象上,所以this.a是4。
函数存在别名调用
function foo() {
console.log( this.a );
}
var a = 2;
var obj = {
a: 3,
foo: foo
};
var bar = obj.foo;
bar(); //2
上面代码中,obj.foo赋值给了bar,由于obj中的foo只是保存着foo方法中的地址引用,bar=obj.foo只是将foo保存的地址赋值给了bar,所以执行bar方法相当于执行了window.bar,所以this是指向window。
当使用this的方法被用作回调函数时
function foo() {
console.log( this.a );
}
var a = 2;
var obj = {
a: 3,
foo: foo
};
setTimeout( obj.foo, 500 ); //2
上面代码中,虽然参数是obj.foo,但是这里的上一个引用关系,所以实际上传的就是foo对象本身的引用。对于setTimeout
的调用,还是 setTimeout -> 获取参数中foo的引用参数 -> 执行 foo 函数,中间没有obj的参与。
当上下文环境改变时,也就是说方法在一个对象里定义却到另外一个对象里执行时,this关键词不再指代原对象,而是指代调用该方法的对象。
当使用this的方法被赋值时
var obj = {
x:1,
foo:function () {
console.log(this.x);
}
};
var obj2 = {
x:2,
bar:null
};
obj2.bar = obj.foo();
foo
方法的this
关键词不会指代obj2对象,而是指代obj
对象,因为调用它的是obj
对象。
new绑定
在js中,new实现的功能包括:创建了一个对象、链接到原型、绑定this值、返回新对象。
var x = 2;
function foo(x) {
this.x = x;
}
var bar = new foo(1);
console.log(bar.x); //1
var bar2 = new foo(3);
console.log(bar2.x) //3
函数每次使用new都会生成一个全新的对象,该对象又会自动绑定到this上;
Apply、Call、Bind方法绑定