JavaScript 函数有 4 种调用方式。每种方式的不同在于 this 的初始化

this 关键字

SRE实战 互联网时代守护先锋,助力企业售后服务体系运筹帷幄!一键直达领取阿里云限量特价优惠。

一般而言,this指向函数执行时的当前对象。

作为一个函数调用

1 <body>
2     <p id="demo"></p>
3     <script>
4     function myFunction(a, b) {
5         return a + b;
6     }
7     document.getElementById("demo").innerHTML = myFunction(5, 3);
8 </script>
9 </body>

结果:浏览器页面输出  8

以上函数不属于任何对象。但是在 JavaScript 中始终是默认的全局对象。

在 HTML 中默认的全局对象是 HTML 页面本身,所以函数属于 HTML 页面。

在浏览器中的页面对象是浏览器窗口(window 对象)。以上函数会自动变为 window 对象的函数。

myFunction() 和 window.myFunction() 是一样

函数作为全局对象调用

当函数没有被自身的对象调用时 this 的值就会变成全局对象。

在 web 浏览器中全局对象是浏览器窗口(window 对象)。

1 <body>
2     <p id="demo"></p>
3     <script>
4         function myFunction() {
5             return this;
6         }
7         document.getElementById("demo").innerHTML = myFunction(); 
8     </script>
9 </body>

结果:浏览器中输出  [object Window]

函数作为方法调用

创建一个对象 (myObject), 对象有两个属性 (firstName 和 lastName), 一个方法 (fullName)

 1 <body>
 2     <p id="demo"></p>
 3     <script>
 4     var myObject = {
 5         firstName:"Tom",
 6         lastName: "Jack",
 7         fullName: function() {
 8             return this.firstName + "" + this.lastName; //this的值为myObject对象
 9         }
10     }
11     document.getElementById("demo").innerHTML = myObject.fullName(); 
12     </script>
13 </body>

结果:浏览器中输出 Tom,Jack

  fullName方法是一个函数。函数属于对象。 myObject是函数的所有者。

修改fullName方法,将this返回:

 1 <body>
 2     <p id="demo"></p>
 3     <script>
 4     var myObject = {
 5         firstName:"Tom",
 6         lastName: "Jack",
 7         fullName: function() {
 8             return this; // this的值成为对象本身
 9         }
10     }
11     document.getElementById("demo").innerHTML = myObject.fullName();
12     </script>
13 </body>

结果:浏览器中输出  [object Object]

此时this的值变成对象本身

使用构造函数调用函数

 1 <body>
 2     <p id="demo"></p>
 3     <script>
 4     function myFunction(arg1, arg2) {
 5         this.firstName = arg1;
 6         this.lastName  = arg2;
 7     }
 8     var x = new myFunction("Tom","Jack");
 9     document.getElementById("demo").innerHTML = x.firstName; 
10     </script>
11 </body>

结果:浏览器输出  Tom

构造函数的调用会创建一个新的对象。新对象会继承构造函数的属性和方法。this 的值在函数调用实例化对象(new object)时创建

作为函数方法调用函数

call( )和 apply( )是预定义的函数方法。 两个方法可用于调用函数,两个方法的第一个参数必须是对象本身

call( )

 1 <body>
 2     <p id="demo"></p>
 3     <script>
 4         var myObject;
 5         function myFunction(a, b) {
 6             return a + b;
 7         }
 8         myObject = myFunction.call(myObject, 5, 3);
 9         document.getElementById("demo").innerHTML = myObject; 
10     </script>
11 </body>

结果:浏览器输出  8

apply( )

 1 <body>
 2     <p id="demo"></p>
 3     <script>
 4         var myObject, myArray;
 5         function myFunction(a, b) {
 6             return a + b;
 7         }
 8         myArray = [5, 3]
 9         myObject = myFunction.apply(myObject, myArray);
10         document.getElementById("demo").innerHTML = myObject; 
11     </script>
12 </body>

两者的区别在于第二个参数: apply传入的是一个参数数组,而call则作为call的参数传入(从第二个参数开始)。

在 JavaScript 严格模式(strict mode)下, 在调用函数时第一个参数会成为this的值, 即使该参数不是一个对象。

在 JavaScript 非严格模式(non-strict mode)下, 如果第一个参数的值是 null 或 undefined, 它将使用全局对象替代。

扫码关注我们
微信号:SRE实战
拒绝背锅 运筹帷幄