论javascript中this和that--《Javascript The Good Parts》读书笔记

目录

示例1

代码:

运行效果:

分析:

this的指向

that的作用

示例2--setTimeout中的this

代码1 (非严格模式)

效果1

代码2(严格模式)

效果2


按照《Javascript The Good Parts》第四章的描述,假如函数是对象的方法,则函数的this指向所属对象。如果函数不是任何对象的属性,那么函数体中的this将指向“global object”,也就是窗体“window”。所以下面这段代码里,helper的this指向的就是window。

示例1

代码:

<html>

<head>

</head>

<body>

<script>
	let myObject = {
		value: 1,
	};
	myObject.double = function ( ) {
		var that = this; // Workaround.
		var helper = function ( ) {
			that.value = that.value + that.value;
			this.test = "test";
		};
		helper(); // Invoke helper as a function.
		document.write(helper.test + "\n");
		document.write(window.test + "\n");
	};
	// Invoke double as a method.
	myObject.double( );
	document.writeln(myObject.value);
</script>

</body>
</html>

运行效果:

分析:

this的指向

第一个this

var that = this; // Workaround.

第一个this处于myObject的成员函数double内,所以this指向myObject

第二个this

第二个this处于helper内,而helper是一个function,根据前面的陈述,this指向window

this.test = "test";

实际的效果也验证了这一点:helper没有test属性,故helper.test打印undefined,而window.test打印test

that的作用

前面说了,myObject.double的this指向myObject。但是,尽管helper定义在double函数的定义内,helper的this却指向window。为了能在helper中操作myObject,利用下面的性质:

函数可以访问其上一级作用域里声明的变量

声明that,将this赋值给that,于是helper就可以获取myObject的value属性并操作。

示例2--setTimeout中的this

根据《Professional Javascript for web developers》的说法:

All code executed by a timeout using a conventional anonymous function
runs in the global scope, so the value of this inside the function will always
point to window when running in nonstrict mode and undefined when running
in strict mode. When setTimeout is instead provided an arrow function, this
preserves the lexical scope in which it was defined。

假如在setTimeout中使用普通的匿名函数,匿名函数将运行在全局作用域,匿名函数中的this指向全局的window(非严格模式)或者undefiend(严格模式)。假如在setTimeout中使用=>函数,函数则运行于其所在的作用域。

代码1 (非严格模式)

<!DOCTYPE html>
<html>
<body>

<h2>My Heading</h2>

<p>Play around with the code and click on the "Run" button to view the result.</p>

<p id="demo"></p>
<p id="demo2"></p>
<p id="demo3"></p>

<script>
// Online Javascript Editor for free
// Write, Edit and Run your Javascript code using JS Online Compiler
var v = 1;
class test
{
    constructor() {
        this.v = 2;
    }
  
    p()
    {
        let f = function(){document.getElementById("demo").innerHTML ="Welcome!" + this.v;};
        setTimeout(f, 1000);
    }
    
    p2()
    {
        setTimeout(() => document.getElementById("demo2").innerHTML ="Welcome again!" + this.v, 1000);
    }
    
    p3()
    {
    	setTimeout(function(){document.getElementById("demo3").innerHTML ="Welcome!" + this.v;}, 1000);
    }
}

let t = new test;
t.p();
t.p2();
t.p3();
</script>

</body>
</html>

效果1

 由于在函数p2中使用了=>定义函数,所以this指向了test。故this.v = 2。另外的两个函数p和p3使用了匿名函数,所以this指向window(非严格模式)。

代码2(严格模式)

// Online Javascript Editor for free
// Write, Edit and Run your Javascript code using JS Online Compiler
var v = 1;
class test
{
    constructor() {
        this.msg = 1;
    }
  
    p()
    {
        let f = function(){console.log("Welcome to Programiz!" + this.v);};
        setTimeout(f, 1000);
    }
    
    p2()
    {
        setTimeout(() => console.log("Welcome to Programiz again!" + this.msg), 1000);
    }
    
    p3()
    {
    	setTimeout(function(){console.log("Welcome to Programiz!" + this.v);}, 1000);
    }
}

let t = new test;
t.p();
t.p2();
t.p3();

效果2

 由于在programiz环境下使用的是严格模式,所以this.v显示为undefined

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值