由于在使用nodejs之前接触js也比较少,最近一直被js的function和new function所困惑,由于两者都可以呈现出面向对象的样子,不知道两者的差别在哪里,就此问题做了一些研究。在研究的过程中发现this指针是个麻烦事,这在js前端使用的时候就已经体会到了,但是在node中的this又和前端js不太一样,也就此对node中的this做了下简单的研究。下面先分享一下对于function和new function的研究,主要是他们用于面向对象设计的方法和比较。
1. 首先,我们这里把function直接调用时将这个function当做方法来看待,而new function是将function当做类来看待。
2. 基于第一点,当把function作为类来使用时,function中的this下的变量都会变成实例化对象的可访问属性(可以理解为public,其实nodejs中的this就是用来定义类的公有变量的,关于this会在下面做进一步的解释),例如function A(){this.x = 1;},则var a = new A();后相当于得到var a = {x:1};this指向这里类生成的对象本身,this.x就相当于将x这个属性暴露出去,而原本function中没有this的都可以看做是私有变量,不能直接访问。
3. function当做方法来看时,即不new,则调用方法时的this指的是这个文件,我们称为文件对象。只有return的东西是可以被外部访问的,内部的数据则是被隐蔽的。
4. 结合2,3两点可以发现,无论是不是new,实际上都有对象的概念,即暴露一些公用方法和变量,隐藏一些私有属性,很多情况下两种设计方法都可以。
5. 对于继承,js中使用prototype来指定类型的原型,即function的原型对象。对于function当做方法来使用则需要将一些需要用到的原型的方法包在返回变量里。而当做类来使用则可以直接用.的形式来访问属性。从这点来说function当做类来表现面向对象的思想用起来要方便的多。
所以综上,如果是严格按照面向对象思想来设计程序,并且牵涉到继承或者大量的对象创建,则需要用到prototype,推荐将function当做类来使用。
ps:其实js的随意有时候是好处,有时候也不好,使用起来会混乱。所以例如function如果当做类时就不要写return了,而如果当做function来用,不要用this(从公有变量角度来说,呈现的效果是一样的,语法上不会有什么问题,但混起来使用会导致程序变得很乱)。
下面介绍一下this的使用,特别是在node下和前端js不同的地方:
nodejs中的this在某个对象中指向这个对象,在某个function中分两种情况:(1)直接调用function,指向文件对象。(2)new function则指向创建的对象。
和浏览器端js的this不同,浏览器端js的this指向的统一是window对象,并且未声明的全局属性也都认为是window对象的属性。例如var a = 9;然后调用alert(this.a)得到的结果就是9,。而在node中,却得不到这样的结果。如果你这样写,var a = 9;console.log(this.a);那么你只能得到undefined。这是因为node中的this表明的是这个文件对象,而this.a并不是说文件内定义的默认属性a,而是这个文件可以被其他js文件访问的属性a。如果另一个js文件require了这个文件,便可以直接得到这个属性值,和exports的效果一样。例如:
//file1.js
this.x = 9;
//file2.js
var f1 = require(“./file1”);
console.log(f1.x);//得到结果9
所以综上,this在nodejs中的作用就是声明对象的共有变量,无论是new出来的对象还是类似var a = {}的对象又或者是整个文件对象。this的使用要时刻和对象的概念绑在一起,不然程序很容易出现问题
恩,是这样子的,其实new fun()就是把方法放到指定的上下文(某个对象)去运行。我写这文是因为开发过程中碰到封装的概念,主要是从如何更好使用面向对象思想来使用js的角度出发的,是讨论直接fun()然后return一个变量组比较好还是new fun()的方式比较好。
函数调用分4种:
直接调用:function aaa(){}; a();
对象调用:a={aaa:function(){}};a.aaa();
构造函数调用:function aaa(){}; var bbb = new aaa();
call,apply调用:
function aaa(){
alert(this.name);
};
var bbb = {name:"xxx"};
aaa.call(bbb, null);// “xxx”
CALL和APPLY的区别在于第二个参数CALL是传按顺序传参,而APPLY是传一个数组参数