我们知道,this对象是在运行时基于执行函数的执行环境绑定:在全局函数中,this等于window,而当函数被当做某个对象的方法调用时,this等于那个对象。
this的使用环境分以下几种情况:
- 普通函数调用
- 作为构造函数调用
- 作为对象的方法来调用
- call/apply/bind方法的调用
普通函数调用
单纯函数调用属于全局调用,this指向this指向Global对象,在浏览器着就是window对象。
var name = "the window";
function fn(){
alert(this.name);
}
fn(); //the window
这个例子很好理解。在全局作用域中声明的变量、函数,都会变成window对象的属性、方法,this指向window
var length = 10
function fn(){
alert(this.length)
}
var obj = {
length: 5,
method: function(fn) {
fn() // ?
arguments[0]() // ?
}
}
obj.method(fn) //10 1
这个例子就不太好理解了。这里fn依然是单纯的函数调用,我们知道,每个函数在被调用时,都会自动取得两个特殊变量:this和arguments。内部函数搜索这两个变量时,只会搜索到其活动对象为止。所以这里fn中的this指向window。
另外要注意arguments是一个对象,对象属于除了点操作符还可以用中括号,arguments[0]()其实是fn作为arguments对象的方法被调用,this指向arguments,因为参数只有一个fn,因此length为1
var length = 10
var obj = {
length: 5,
method: function() {
function fn(){
alert(this.length)
}
fn();
}
}
obj.method() //10
再稍微变换一下代码,this依然指向window
作为对象的方法调用
函数被作为某个方法时,this等于那个对象
var length = 10
function fn(){
alert(this.length)
}
var obj = {
length: 5,
method: fn
}
obj.method() //5
再换一个例子
function fn(){
alert(this.length)
}
var obj1 = {
length: 5,
method: fn
}
var obj2 = {
length: 6,
method: obj1.method
}
obj2.method() //6
作为构造函数调用
通过new操作符来调用函数,创建一个新的对象,将构造函数的作用域赋予给新对象,因此this指向这个新对象。
var name = "windowName";
function fn(name){
this.name = name;
this,sayName = function(){
alert(this.name);
}
}
fn("fnName"); //fnName
call/apply/bind方法的调用
这三个方法都是通过传递参数改变函数体内的this。call和apply方法的作用相同,函数体内的this指向的第一个参数。
var name = "window";
var o = {
name: "object"
};
function fn(){
alert(this.name)
}
fn.call(this); //window
fn.call(window); //window
fn.call(o); //object
var obj1 = {
n1:"n1",
n2:"n2"
};
var obj2 = {
n1:"nn1",
n2:"nn2",
fn:function(x,y){
this.n1 = x;
this.n2 = y;
}
};
obj2.fn.call(obj1,"new1","new2");
console.log(obj1.n1); // new1
console.log(obj1.n2); // new2
console.log(obj2.n1); // nn1
console.log(obj2.n2); // nn2
bind方法会创建一个函数的实例,其this值会被绑定到传给bind()函数的值
var obj1 = {
n1:"n1",
n2:"n2"
};
var obj2 = {
n1:"nn1",
n2:"nn2",
fn:function(x,y){
this.n1 = x;
this.n2 = y;
}
};
var obj = obj2.fn.bind(obj1);
obj("new1","new2");
console.log(obj1.n1); // new1
console.log(obj1.n2); // new2
console.log(obj2.n1); // nn1
console.log(obj2.n2); // nn2
参考资料
关注作者吧~
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。