全局变量

global

global是全局对象。所有在node进程里的对象都挂在global上。global和BLOBAL看起来是一个同一个东西且是一回事。确实,Global是global一个别名。

定义一个全局变量

global.name = 'xm'   
Global.name = 'xm'   
name = 'xm'

删除全局变量

delete global.name

几个常用全局变量

console.log(__dirname);//当前路径
console.log(__filename);//当前在执行的js文件路径
console.log(process.env);//环境变量

process.on('exit', function(code) {
      // 以下代码永远不会执行
      setTimeout(function() {
        console.log("该代码不会执行");
      }, 0);
      console.log('退出码为:', code);
    });
    console.log("程序执行结束");

模块内全局变量

如果使用var关键字声明的变量将会保留在本地模块里;这些声明的变量没有附加到global对象里。

var company = 'Yahoo';

其他模块引用模块内变量

var company = require('./main').company;
console.log(company);

因此一个包体中,有2钟创建node全局变量的方法,一个是使用global对象,另一个是使用modules.exports。哪个是我推荐的呢?global方法适用小的应用,modules.exprots适用于大的应用。

模块导入require

引用(include)一个已经被其他模块引用过的模块时,仅仅创建一个指向之前包体的引用,因此这意味着不会极度消耗内存。也因为没有重新创建一个真正的包体,在module里的所有初始化方法没有再执行。

this

this关键字是在真正被执行到的时候才会发挥作用。this对象仍然是指代函数被执行时执行该函数的对象。

下面分四种情况,详细讨论this的用法

情况一:纯粹的函数调用

这是函数的最通常用法,属于全局性调用,因此this就代表全局对象Global。

x=1;
function test(){
    console.log(this.x);//=>1
    x=2;
}
test(); // 1
console.log(x);//=>1

情况二:作为对象方法的调用

函数还可以作为某个对象的方法调用,这时this就指这个上级对象。

function test(){
    console.log(this.x);
}
var o = {};
o.x = 1;
o.m = test;
o.m(); // 1

情况三 作为构造函数调用

构造函数,就是通过这个函数生成一个新对象(object)。这时,this就指这个新对象。

function test(){
    this.x = 1;
}
var o = new test();
console.log(o.x); // 1

情况四 apply/call调用

apply()是函数对象的一个方法,它的作用是改变函数的调用对象,它的第一个参数就表示改变后的调用这个函数的对象。因此,this指的就是这第一个参数。

x = 0;
function test(){
    console.log(this.x);
}
var o={};
o.x = 1;
o.m = test;
o.m.apply(); //0

apply()的参数为空时,默认调用全局对象。因此,这时的运行结果为0,证明this指的是全局对象。
如果把最后一行代码修改为

o.m.apply(o); //1

运行结果就变成了1,证明了这时this代表的是对象o。

情况五:闭包下

var object = {
  name : "My Object",
  getNameFunc : function(){
    return function () {
      return this.name;
    };
  }
};
name = "global";
console.log(object.getNameFunc()());//=》global  类似于情况一,闭包下调用this为全局变量
var obj = {
  name : "last",
  myf : object.getNameFunc()
};
console.log(obj.myf());//=》last把object.getNameFunc()赋值给myf是,实际等价于将函数function (){ return this.name; }

call与apply

两个方法的调用作用都是讲一个函数的对象上下文从初始的上下文改变为指定的新对象。

call(thisObj, arg1, arg2, ...)
apply(thisObj, argArray)

实例:

函数对象替换

function add(a,b)
{
    console.log(a+b);
}
function sub(a,b)
{
    console.log(a-b);
}
add.call(sub,3,1);//=>4

对象多态性

function Animal(){
    this.name = "Animal";
    this.showName = function(){
        console.log(this.name);    
    }
}

function Cat(){
    this.name = "Cat";
}

var animal = new Animal();
var cat = new Cat();

//通过call或apply方法,将原本属于Animal对象的showName()方法交给对象cat来使用了。
//输入结果为"Cat"
animal.showName.call(cat,",");
//animal.showName.apply(cat,[]);

对象继承

function Animal(name){
    this.name = name;
    this.showName = function(){
        console.log(this.name);
    }
}

function Cat(name){
    Animal.call(this, name);
}

var cat = new Cat("Black Cat");
cat.showName();

多重继承

function Class10()
{
    this.showSub = function(a,b)
    {
        console.log(a-b);
    }
}

function Class11()
{
    this.showAdd = function(a,b)
    {
        console.log(a+b);
    }
}

function Class2()
{
    Class10.call(this);
    Class11.call(this);
}

new Class2().showAdd(1,2);//=>3

arguments

arguments是函数的实际参数对象

function test(a,b,c) {
    console.log(arguments);
}

test(1,2,3);//=>{ '0': 1, '1': 2, '2': 3 }

将函数的实际参数转换成数组的方法

方法一:

var args =Array.prototype.slice.call(arguments);

方法二:

var args = [].slice.call(arguments, 0);

方法三:

var args = []; 
for (var i = 1; i < arguments.length; i++) { 
    args.push(arguments[i]);
}

未完…