02月05, 2012

作用域 和 封装

不知道大家是不是经常会混淆 作用域 和 封装, 这两个概念。

作用域,是指一个名字,它可以被直接使用的范围,,作用域可以被局部的定义体遮蔽。

而封装,是限定一个成员的可访问范围,是oop提到的三个基础思想(oop三大基础思想:继承,封装,多态)。 作用域:

因为js不存在块级的作用域,,只存在函数作用域,且函数可被嵌套定义,,所以一个变量的作用域可被嵌套函数中同名变量的作用域遮蔽。

封装:

js中其实是没有封装这个概念的,,不过我们可以模拟出封装的效果:

用var xx=1和this.xx=1来模拟封装,把this上的成员视为公开成员,var的成员视为私有成员。

其实this.xx,这个xx并不在函数的符号表上,因为我们即使在this的成员函数中,都没办法不用this来限定访问this上的成员,,除非我们用with(this)的形式创建一个动态作用域。

function F(){
var self = this;
this.a = 1;
this.xx = function(){
this.a = 2;

with(self){
a=3; //with创建了一个动态作用域,把self的所有成员都展开到符号表了
}
with(this){
a=4;
}
a=5; //在F和thix.xx两个函数的符号表上都找不到a
}
}
var ins1 = new F;
(1,ins1.xx)()
console.log(ins1.a, a); //3,5 with(this)打开的是window

var ins2 = new F;
ins2.xx()
console.log(ins2.a, a); //4,5 whit(this)打开的是ins2

在java,c++等编程语言中,实现封装特性的关键字是访问修饰符,访问修饰符有public protected private。

而javascript是没有在语言上来提供封装这种功能的,我们只能依赖闭包特性,来模拟出封装这种功能。

另外,作用域也要分清楚词法作用域和动态作用域,,词法作用域提供的信息,可以让js脚本运行时对脚本的执行进行优化,而动态作用域是在运行时才确定作用域信息,,所以无法开启这些优化,,所以我们也要避免动态作用域。

本文链接:https://75team.com/post/作用域-和-封装.html

-- EOF --

Comments

评论加载中...

注:如果长时间无法加载,请针对 disq.us | disquscdn.com | disqus.com 启用代理。