JavaScript面向对象之上下文规则
1583 字
8 分钟
JavaScript面向对象之上下文规则
本文主要学习面向对象中的上下文规则,以及怎么改变上下文
认识上下文
函数的上下文
- 函数中可以使用this关键字,它表示函数的上下文
- 与中文中“这”类似,函数中的this具体指代什么必须通过调 用函数时的“前言后语”来判断
函数中的this
var xiaoming = { nickname : '小明', age : 12, sayHello : function () { console.log('我是' + this.nickname + ',我' + this.age + '岁了'); }};xiaoming.sayHello();//我是小明,我12岁了函数被提出到外面执行:
var xiaoming = { nickname : '小明', age : 12, sayHello : function () { console.log('我是' + this.nickname + ',我' + this.age + '岁了'); }};var sayHello = xiaoming.sayHello;//将函数“提”出来,单独存为变量sayHello();//直接圆括号调用这个函数而不是对象打点调用了 我是undefined,我undefined岁了-
同一个函数,用不同的形式调用它,则函数的上下文不同
-
情形1:对象打点调用函数,函数中的this指代这个打点的对象
xiaoming.sayHello(); -
情形2:圆括号直接调用函数,函数中的this指代window对象
var sayHello = xiaoming.sayHello;sayHello();
函数的上下文由调用方式决定
var obj = { a: 1, b: 2, function () { console.log(this.a + this.b);//不知道,因为没有调用,函数只有被调用,它的上下文才能被确定 }};例子1:
var obj = { a: 1, b: 2, fn: function () { console.log(this.a + this.b); }};obj.fn();//this指向obj例子2:
var obj = { a: 1, b: 2, fn: function () { console.log(this.a + this.b); }};var fn = obj.fn;fn();this指向window上下文规则
函数的上下文由调用函数的方式决定
- 函数的上下文(this关键字)由调用函数的方式决定, function是“运行时上下文”策略
- 函数如果不调用,则不能确定函数的上下文
规则1
-
规则1:对象打点调用它的方法函数,则函数的上下文是这 个打点的对象
对象.方法()function fn() {console.log(this.a + this.b);}var obj = {a: 66,b: 33,fn: fn,};obj.fn(); //99var obj1 = {a: 1,b: 2,fn: function () {console.log(this.a + this.b);},};var obj2 = {a: 3,b: 4,fn: obj1.fn,};obj2.fn(); //7function outer() {var a = 11;var b = 22;return {a: 33,b: 44,fn: function () {console.log(this.a + this.b);},};}outer().fn(); //77function 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(); //7
规则2
-
圆括号直接调用函数,则函数的上下文是window对 象
函数()var obj1 = {a: 1,b: 2,fn: function () {console.log(this.a + this.b);},};var a = 3;var b = 4;var fn = obj1.fn;fn();//7function fun() {return this.a + this.b;}var a = 1;var b = 2;var obj = {a: 3,b: fun(),//3fun: fun,//obj.fun === window.fun true};var result = obj.fun();//6,一个铁律:函数只有在调用的时候才能确定上下文 obj.a + obj.b 3+3console.log(result);//6
规则3
-
数组(类数组对象)枚举出函数进行调用,上下文 是这个数组(类数组对象)
数组[下标]()var arr = ['A','B','C',function () {console.log(this[0]);},];arr[3]();'A'
类数组对象
-
什么是类数组对象:所有键名为自然数序列(从0开始), 且有length属性的对象
-
arguments对象是最常见的类数组对象,它是函数的实参列 表
function fun() {arguments[3]();}fun('A', 'B', 'C', function () {console.log(this[1]);});//’B‘
规则4
-
IIFE中的函数,上下文是window对象
(function() {})();var a = 1;var obj = {a: 2,fun: (function () {var a = this.a;//1 IIFE中的函数,上下文是window对象所以这里this指向全局a 即1return function () {console.log(a + this.a);//这里的this取决于调用,obj.fun(),所以this是obj,即a等于2 ,1+2=3};})(),};obj.fun();//3
规则5
-
定时器、延时器调用函数,上下文是window对象
setInterval(函数, 时间);setTimeout(函数, 时间);var obj = {a: 1,b: 2,fun: function () {console.log(this.a + this.b);},};var a = 3;var b = 4;setTimeout(obj.fun, 2000);//定时器、延时器调用函数,上下文是window对象,所以这里指向的不是obj,虽然是obj调用,但是是setTimeout里面调用所以是window对象,所以是7,注意这里obj.fun并没有执行,而是2秒后执行var obj = {a: 1,b: 2,fun: function () {console.log(this.a + this.b);},};var a = 3;var b = 4;setTimeout(function () {obj.fun();//这里已经执行,函数这里指向obj,所以是3,2秒后也是3}, 2000);
规则6
-
事件处理函数的上下文是绑定事件的DOM元素
DOM元素.onclick = function () {}; -
请实现效果:点击哪个盒子,哪个盒子就变红,要求使用同 一个事件处理函数实现
<style> .box { width: 100px; height: 100px; border: 1px solid #000; margin: 10px; display: inline-block; } </style> </head> <body> <div class="box"></div> <div class="box"></div> <div class="box"></div> <div class="box"></div> <script> var boxes = document.querySelectorAll('.box');
for (var i = 0; i < boxes.length; i++) { boxes[i].onclick = changeColor; }
function changeColor() { this.style.backgroundColor = 'red'; } </script> </body>-
请实现效果:点击哪个盒子,哪个盒子在2000毫秒后就变红 ,要求使用同一个事件处理函数实现
var boxes = document.querySelectorAll('.box');for (var i = 0; i < boxes.length; i++) {boxes[i].onclick = changeColor;}function changeColor() {var that = this; // 保存当前点击的盒子setTimeout(function () {that.style.backgroundColor = 'red';}, 2000);}
call和apply
call和apply能指定函数的上下文
先来看个例子:
function sum() { alert(this.chinese + this.math + this.english);}var xiaoming = { chinese: 80, math: 95, english: 93,};//想用xiaoming调用sum,就需要sum成为xiaomin的上下文也就是下面var xiaoming = { chinese: 80, math: 95, english: 93, sum:sum};但是现在有更简单的方式:
sum.call(xiaoming);sum.apply(xiaoming);就可以让sum的上下文成为xiaomin对象的上下文
function sum() { // alert(this.chinese + this.math + this.english); console.log(this.chinese + this.math + this.english);}var xiaoming = { chinese: 80, math: 95, english: 93,};sum.call(xiaoming);sum.apply(xiaoming);call和apply的区别
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要把参数写到数组中到底使用call还是apply?
function fun1() { fun2.apply(this, arguments);//arguments是类数组,所以只能使用apply}function fun2(a, b) { console.log(a + b);}fun1(33, 44);//77上下文规则总结
| 规则 | 上下文 |
|---|---|
| 对象.函数() | 对象 |
| 函数() | window |
| 数组[ 下标 ] () | 数组 |
| IIFE | window |
| 定时器 | window |
| DOM事件处理函数 | 绑定DOM的元素 |
| call和apply | 任意指定 |
文章分享
如果这篇文章对你有帮助,欢迎分享给更多人!
相关文章智能推荐
1
JavaScript面向对象
前端工程师2026-10-20
2
JavaScript面向对象之类和实例
前端工程师2026-10-20
3
JavaScript的DOM之事件
前端工程师2026-10-20
4
JavaScript的DOM之节点
前端工程师2026-10-20
5
JavaScript函数
前端工程师2026-10-19
随机文章随机推荐














