和浏览器里面不同的地方:
创建 main.js
function test() {
this.names = "anikin";
}
this.names = 'zhangsan';
test();
console.log(this, this.name) // {} zhangsan
console.log(global.names) // aninkin
// 在打印一下看看这个this指向哪里呢
console.log(this === module.exports); // true
通过上面的代码分析得出几个结论:
- 函数里面的
this
指向的是全局的global
。 - 整个运行文件里面的
this
是指向module.exports
的。这个可以参考模块化原理。
我们都知道 exports = module.exports
,是存在引用关系的,内存引用一般也是服从堆栈调用的规则。因此我们可以使用this
来验证一下。
js 里面很基础的引用关系。
var a = { name: "anikin" };
var b = a;
a = { age: 23 };
console.log(a, b);
输出结果是: { age: 23 } { name: "anikin" }
。
所以验证下上面的exports
的关系。新建文件test.js
:
console.log(this === exports); // true
console.log(this === module.exports); // true
//
exports.c = 3;
module.exports = {
a: 1,
b: 2,
};
this.m = 5;
console.log(this);
console.log(this === exports);
console.log(this === module.exports);
console.log(module.exports);
以此输出结果是:
{ c: 3, m: 5 }
true
false
{ a: 1, b: 2 }
解释:在读取文件的时候,内部会调用访问文件函数:__temp.call
-
在访问模块的时候
this
指向的是module.exports
,而module.exports
为一个空对象,exports = module.exports
;所以为什么开头一开始问什么打印的全部都是空对象,require
函数返回的是module.exports
,此时返回的是一个空对象{}
。 -
exports
值也是空对象{}
,当给exports
赋值时:exports.c=3
;此时值为一个引用值,相当于改变了堆地址内的值,但是引用堆房间的地址不变,所以修改exports
的值module.exports
也会改变,还是空对象{c:3}
,此时的this
也是{c:3}
-
module.exports={a:1,b:2}
;现在是改变了值,就相当于在堆中创建了一个新地址引用,然后指向新的房间,
所以this
指向的还是原来的引用,故this
与module.exports
不相等,但是this
和exports
还是相等的
和浏览器相同的点:
类似对象,类,已经箭头函数等的this
可以参考浏览器端的实现。
例如箭头函数:this
是在定义函数时绑定的,不是在执行过程中绑定的。简单的说,函数在定义时,this就继承了定义函数的对象。
const Events = require("events");
class MyEvent extends Events {}
var e1 = new MyEvent();
e1.on("start", function () {
console.log("start:event ", this, this === e1);
});
e1.on("start", () => {
console.log("start:event ", this, this === e1);
});
e1.emit("start", "anikin");
执行结果是:
anikin MyEvent true
{} false
常见问题FAQ
- 免费下载或者VIP会员专享资源能否直接商用?
- 本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
- 提示下载完但解压或打开不了?
- 找不到素材资源介绍文章里的示例图片?
- 模板不会安装或需要功能定制以及二次开发?
发表评论
还没有评论,快来抢沙发吧!