- this是一个全局变量,初始时指向window(非严格模式)或undefined(严格模式)。
- 标准函数作为方法(即对象的函数)调用时,this为调用对象;作为函数调时this为window对象。注意,这个对象还包括数组和函数,它们是特殊类型的对象。
- 嵌套函数的内层函数中的this总是window,因为此时不是作为方法调用。
- 箭头函数中的this总是沿用定义时上下文的。
示例代码如下:
<html>
<head>
<script>var name = 'win';(function(){ /* 测试严格模式下全局指针this */"use strict"; /* 函数内部使用严格模式 */console.log(!this); /* 输出true。严格模式下,全局指针this为undefined,不是window */(()=>console.log(this))(); /* 输出undefined。严格模式下,全局指针this为undefined,不是window */}());function Foo(){ /* 构造函数 */(()=>console.log(this.name))(); // IIFE即时调用表达式,1输出undfined,定义时this为新建对象,但此时name未定义this.name = 'foo';(()=>console.log(this.name))(); // IIFE即时调用表达式,2输出foo,定义时this为新建对象,此时name为foothis.f1 = ()=>console.log(this.name); // 箭头函数this.f2 = function(){console.log(this.name);} // 标准函数this.f3 = function(){(function(){console.log(this.name);}());} // 内嵌函数为IIFE即时调用表达式this.f4 = ()=>{(function(){console.log(this.name);}());} // 外箭头内标准函数this.f5 = ()=>{(()=>console.log(this.name))();} // 两个嵌套的箭头函数}var obj = { name: 'obj' } // 字面对象量var foo = new Foo(); // 创建foo对象foo.f1.call(obj); // 3输出foo,箭头函数调用,定义时this为foo对象foo.f2.call(foo); // 4输出foo,方法调用,this为调用对象,此时为foofoo.f2.call(obj); // 5输出obj,方法调用,this为调用对象,此时为objfoo.f3.call(obj); // 6输出win,嵌套的两个标准函数,内层函数的this为window对象foo.f4.call(obj); // 7输出win,内层是嵌套的标准函数,this为windowfoo.f5.call(obj); // 8输出foo,嵌套的两个箭头函数,定义时this为foo对象(foo.f2)(); // 9输出foo,仍然作为方法调用,等价foo.f2()调用,this是foovar f6 = foo.f2; // 定义了一个函数f6,其函数体为f2f6(); // 10输出win,作为函数调用,this是window (f6 = foo.f2)(); // 11输出win,赋值语句的结果为右值,等于函数体foo.f2,等价f2的调用function f7(){} // 声明一个具名函数var a1 = []; // 声明一个数组foo.f2.call(foo.f2); // 12输出空字符串'',构造函数中的f2是函数表达式的值,等价匿名函数,name为空字符串foo.f2.call(f6); // 13输出空字符串'',f6是函数表达式的值,等价匿名函数,name为空字符串foo.f2.call(f7); // 14输出f7,作为函数调用,this是具名函数f7,其name属性值为f7foo.f2.call(a1); // 15输出undefined,作为函数调用,this是数组a1,无默认name属性a1.name = 'a1';foo.f2.call(a1); // 16输出a1,作为函数调用,this是数组a1,name值是a1
</script>
</head>
<body>
</body>
</html>