pomelo源码分析(5)--node.js中的this
2017-08-26 22:36
483 查看
作者:shihuaping0918@163.com,转载请注明作者
在继续分析代码之前,需要先讲一下node.js中的this是什么。因为不讲这个的话,后面的内容进行不下去。在以前版本的node.js中,全局this是个空对象,在node8的repl中,全局this和global是相等的。
但是,如果使用node8执行js文件,全局this是个空对象。
好,这个很操蛋的事实还是要接受的。node.js中的this和浏览器中的this又是不一样的。忘掉在浏览器中的经验吧,只要记得this只能随着函数走就行了。为了不影响三观,后面的js语句都只能在文件中写好,然后再用node去执行它。
在C++/java中,this永远都是和某个对象相关的,this生存在类作用域中,隐式存在着。但是在node.js中,它的行为很是诡异。
一、在普通函数中的this,实际上是在引用global,如果你不相信,就执行一下下面的代码。记得先保存文件,然后再执行文件。
二、this作用域是和函数紧密相关的。来看段稍微长一点的代码。
这段代码是执行不了的,语法报错。执行环境node8,其它的环境也许能通过。在console.log({other:other})引用了函数one作用域里的other。都是不合法的。
那什么情况是合法的,只有引用作用域内的才合法。
代码证明,同名变量可以在不同作用域存在,不同作用域引用同名变量得到的值不同。也就是存在作用域同名变量覆盖的情况。
三、“构造函数”的this指向的是它自己,而不是global。
四、this魔幻走位,上面看的例子都还好理解,下面来一个让人觉得很诡异的例子。
惊喜不惊喜,意外不意外?name和age前不加this是执行不了的,因为作用域问题。但是加上以后呢,为什么输出的和java/c++中的完全不一样。原因就是this是随着执行上下文发生改变的。ecma5提供了一个bind方法,bind可以指定一个this参数,以确保函数在执行的时候,里面的this永远是bind时的那个this,而不会随着调用上下文发生变化。
最后总结一下:
1.在js中,创建一个作用域的唯一方法就是使用function关键字。for循环,case之类的都不行。这和c++/java是不一样的。
2.var声明的变量在整个当前域都是有效的,而且它会覆盖外部同名变量。
3.this和arguments是随着代码调用位置的变化而变化的。每个嵌套层次切换时都发生变化。
在继续分析代码之前,需要先讲一下node.js中的this是什么。因为不讲这个的话,后面的内容进行不下去。在以前版本的node.js中,全局this是个空对象,在node8的repl中,全局this和global是相等的。
> this === global true >
但是,如果使用node8执行js文件,全局this是个空对象。
console.log(this) let result = this === global console.log(result) 执行结果: {} false
好,这个很操蛋的事实还是要接受的。node.js中的this和浏览器中的this又是不一样的。忘掉在浏览器中的经验吧,只要记得this只能随着函数走就行了。为了不影响三观,后面的js语句都只能在文件中写好,然后再用node去执行它。
在C++/java中,this永远都是和某个对象相关的,this生存在类作用域中,隐式存在着。但是在node.js中,它的行为很是诡异。
一、在普通函数中的this,实际上是在引用global,如果你不相信,就执行一下下面的代码。记得先保存文件,然后再执行文件。
function fn(){ this.num = 10; } fn(); console.log(this); {} console.log(this.num); undefined console.log(global.num); 10
二、this作用域是和函数紧密相关的。来看段稍微长一点的代码。
var name = "like global..."; function one() { var name = "in func one..."; var other = "somewhat..."; function two() { var name = "in func two..."; console.log({name: name, other: other}); } two(); console.log({name: name, other: other}); } one(); console.log({name: name}); console.log({other: other});
这段代码是执行不了的,语法报错。执行环境node8,其它的环境也许能通过。在console.log({other:other})引用了函数one作用域里的other。都是不合法的。
那什么情况是合法的,只有引用作用域内的才合法。
var name = "like global..."; function one() { var name = "in func one..."; var other = "somewhat..."; function two() { var name = "in func two..."; console.log({name: name,other:other }); } two(); console.log({name: name, other: other}); } one(); console.log({name: name});
代码证明,同名变量可以在不同作用域存在,不同作用域引用同名变量得到的值不同。也就是存在作用域同名变量覆盖的情况。
三、“构造函数”的this指向的是它自己,而不是global。
function Person(name,age) { this.name = name; this.age = age; } let p1 = new Person("lilei", 50); let p2 = new Person("hanmeimei",45); console.log(p1); console.log(p2); console.log(global.name); console.log(global.age);
四、this魔幻走位,上面看的例子都还好理解,下面来一个让人觉得很诡异的例子。
let Person = { name : "sam", age : 18, foo: function() { console.log(this.name + ",how old are you?", this.age); } }; let Pet = { name : "dog", age : 3, foo : Person.foo }; Pet.foo(); 输出结果为 dog,how old are you? 3
惊喜不惊喜,意外不意外?name和age前不加this是执行不了的,因为作用域问题。但是加上以后呢,为什么输出的和java/c++中的完全不一样。原因就是this是随着执行上下文发生改变的。ecma5提供了一个bind方法,bind可以指定一个this参数,以确保函数在执行的时候,里面的this永远是bind时的那个this,而不会随着调用上下文发生变化。
最后总结一下:
1.在js中,创建一个作用域的唯一方法就是使用function关键字。for循环,case之类的都不行。这和c++/java是不一样的。
2.var声明的变量在整个当前域都是有效的,而且它会覆盖外部同名变量。
3.this和arguments是随着代码调用位置的变化而变化的。每个嵌套层次切换时都发生变化。
相关文章推荐
- node.js源码分析 <一>
- 【Pomelo源码分析】2016-09-21 程序入口(app.js, pomelo.js, application.js)
- node.js require 实现机制初窥;pomelo代码分析5----------- pomel-loader模块
- Node.js-require() 源码解读
- MyBatis-3.4.2-源码分析2:解析XML之settingsAsProperties(root.evalNode("settings"))
- Red hat Linux 安装Node.js 源码安装
- [原创]Backbone源码分析-JSMVC
- 【 js 模块加载 】深入学习模块化加载(node.js 模块源码)
- 网易开源基于Node.js的游戏服务器框架pomelo
- node.js npm权限问题try running this command again as root/Administrator.
- Underscore.js源码分析(一)
- node.js基础模块http、网页分析工具cherrio实现爬虫
- Node.js开发入门—HelloWorld再分析
- RT-Thread finsh源码分析: finsh_node.c
- Backbone.js源码分析系列之Collection模块
- 【图文】Ubuntu系统源码方式编译安装node.js以及express安装出现找不到命令的问题
- 从源码分析Node之require
- Node.js开发入门(二)——HelloWorld再分析
- Spark SQL Catalyst源码分析之TreeNode Library
- Node.js性能分析神器Easy-Monitor