JS:函数的上下文、上下文规则、call和apply指定上下文
JS中函数的上下文和上下文规则一、函数的上下文函数中可以使用this关键字,它表示函数的上下文函数中的this具体指代什......
JS中函数的上下文和上下文规则
一、函数的上下文
- 函数中可以使用this关键字,它表示函数的上下文
- 函数中的this具体指代什么必须通过调用函数时的“前言后语”来判断
- 函数的上下文由调用方式决定
1.情形1:对象打点调用函数,函数中的this指代这个打点的对象xiaoming.sayHello()
2. 情形2:圆括号直接调用函数,函数中的this指代window对象var sayHello =xiaoming.sayHello;
sayHello();
总之,函数只有被调用,它的上下文才能被决定
(1)规则一:对象打点调用它的方法函数,则函数的上下文是这个打点的对象 对象.方法()-->对象
function fun() { console.log(this.a + this.b); } var obj = { a: 1, b: 2, c: [{ a: 3, b: 4, c: fun }] }; var a = 5; obj.c[0].c(); //构成对象.方法()的 形式,适用规则1 结果为7
2)规则二:圆括号直接调用函数,则函数的上下文是window对象 函数()-->window
function fun() { return this.a + this.b; } var a = 1; var b = 2; var obj = { a: 3, b: fun(), //适用于规则2 window对象 3 fun: fun }; var result = obj.fun(); //适用于规则1 结果为6 console.log(result);
(3)规则三:数组(类数组对象)枚举出函数进行调用,上下文是这个数组(类数组对象) 数组[下标]()-->数组
var arr = ['A', 'B', 'C', function () { console.log(this[0]); }]; arr[3](); //A
(4)规则四:IIFE(立即调用函数表达式,自执行匿名函数)中的函数,上下文是window对象 IIFE-->window
(function() { })(); var a = 1; var obj = { a: 2, fun: (function () { //IIFE立即执行,返回内层函数 var a = this.a; //适用规则4,this.a是window a属性即1 return function () { console.log(a + this.a); //前面指闭包中的a值,即1,this.a是规则1中 2 } //适用规则4 })() //最后结果3 }; obj.fun() //适用规则1 即2
(5)规则五:定时器、延时器调用函数,上下文是window对象setInterval(函数, 时间);
setTimeout(函数, 时间); 定时器或者延时器-->window
var obj = { a: 1, b: 2, fun: function () { console.log(this.a + this.b); } } var a = 3; var b = 4; setTimeout(obj.fun, 2000); //适用规则五 7 var obj = { a: 1, b: 2, fun: function () { console.log(this.a + this.b); } } var a = 3; var b = 4; setTimeout(function () { //延时器调用的是外层的匿名函数 obj.fun(); //适用规则1 //真正调用函数的不再是延时器,而是obj.fun调用的。 }, 2000);
(6)规则六:事件处理函数的上下文是绑定事件的DOM元素 dom时间处理函数-->绑定的dom
DOM元素."token operator">= function () { };
(7)call和apply能指定函数的上下文 call和apply-->任意指定
函数.call(上下文); //sum.call(xiaoming) 函数.apply(上下文); //sum.apply(xiaoming) function sum() { alert(this.chinese + this.math + this.english); } var xiaoming = { chinese: 80, math: 95, english: 93 } sum.call(xiaoming) sum.apply(xiaoming) function sum(b1, b2) { alert(this.c + this.m + this.e + b1 + b2); } sum.call(xiaoming, 5, 3); //call要用逗号罗列参数 sum.apply(xiaoming, [5, 3]); //apply要把参数写到数组中
(8)使用new调用的函数-->秘密创建出的对象
class Person { constructor(name, age){ this.name = name; this.age = age; } } person = new Person("zs", 18); console.log(person) //{ name: 'zs', age: 18 }