来自经典论坛的一个经典例子

今天在怿飞的博客上瞎逛看到的,顺便去了经典的帖子,刚好复习一下。这个回帖明确描述了几个非常重要的概念:对象,重载,原型…认真看基本可以弄懂了。

function foo(){
    foo.abc = function(){
        alert('def');
    };
    this.abc = function(){
        alert('xyz');
    };
    abc = function(){
        alert('@@@@@');
    };
    var abc = function(){
        alert('$$$$$$');
    };
}
foo.prototype.abc = function(){
    alert('456');
};
foo.abc = function(){
    alert('123');
};
var f = new foo();
f.abc();
foo.abc();
abc();

摘抄总结:

var f = new foo();
对象初始化,在全局环境中申请空间,执行类定义的构造函数进行初始化。(这个例子没有构造函数)

f.abc();
初始化之后f对象即获得foo类的所有非静态方法,即类中通过this.abc(){...;}来定义的方法,this指针看看这篇文章

foo.abc();
类似于静态语言中的静态方法,即不需要进行对象初始化即可使用,即类中通过foo.abc(){…;}定义的方法。但是Javascript中静态函数的含义又跟静态方法又有所不同,静态语言中的静态方法是没办法访问非静态局部变量的,但这个貌似可以。

var abc;
abc;
有var表明创建的变量是局部变量,只在函数内生效,没有var则是全局变量。这点在控制闭包过程中中需要注意。

foo.prototype.abc = function(){...;}
Javascript是动态语言,不需要进行编译后才运行。在这里使用prototype进行即时创建和绑定方法,如果方法名跟原来类中创建的方法同名,比如例子中有另外的abc();,则使用原型链的方式进行选择和运行。

这个回帖跟以上内容相似,但涉及到delete操作符

function foo(){
    foo.abc = function(){
        alert('def');
    };
    this.abc = function(){
        alert('xyz');
    };
    abc = function(){
        alert('@@@@@');
    };
    eval("var abc = function(){alert('$$$$$$')}");
}
foo.prototype.abc = function(){
    alert('456');
};
foo.abc = function(){
    alert('123');
};
var f = new foo();
delete f.abc;
f.abc();
delete f.abc;
f.abc();
abc();

文章中看出,这个例子很明显要区分开什么时候delete操作符能够在执行环境中删除对象,什么时候对象没有被删除。

比如通过原型链创建(prototype)的属性(方法)不能被删除。即在执行第一次delete f.abc();,删除了f对象中由构造创建的this.abc();方法,故第一个f.abc();应该执行原型链中的alert('456');。而f由原型创建的abc方法还存在原型链中,不能被delete操作符删除掉,故第二个f.abc();依旧执行alert('456');。而最后的abc();则是由foo对象创建的全局方法,不受delete的影响,正常执行alert('@@@@@');

本文来自: http://yyfrankyy.com/blog/330

留言