来自经典论坛的一个经典例子
今天在怿飞的博客上瞎逛看到的,顺便去了经典的帖子,刚好复习一下。这个回帖明确描述了几个非常重要的概念:对象,重载,原型…认真看基本可以弄懂了。
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();,则使用原型链的方式进行选择和运行。
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('@@@@@');。