045_对象作用域

1. 公用、私有和受保护作用域

1.1. 在传统的面向对象程序设计中, 主要关注于公用和私有作用域。公用作用域中的对象属性可以从对象外部访问, 即开发者创建对象的实例后, 就可使用它的公用属性。而私有作用域中的属性只能在对象内部访问, 即对于外部世界来说, 这些属性并不存在。这意味着如果类定义了私有属性和方法, 则它的子类也不能访问这些属性和方法。

1.2. 受保护作用域也是用于定义私有的属性和方法, 只是这些属性和方法还能被其子类访问。

2. JavaScript只有公用作用域

2.1. 对JavaScript讨论上面这些作用域几乎毫无意义, 因为JavaScript中只存在一种作用域, 公用作用域。JavaScript中的所有对象的所有属性和方法都是公用的。因此, 定义自己的类和对象时, 必须格外小心。记住, 所有属性和方法默认都是公用的!

3. 建议性的解决方法

3.1. 许多开发者都在网上提出了有效的属性作用域模式, 解决了JavaScript的这种问题。

3.2. 由于缺少私有作用域,开发者确定了一个规约,说明哪些属性和方法应该被看做私有的。这种规约规定在属性前后加下划线:

obj._color_ = "blue";

3.3. 这段代码中, 属性color是私有的。注意, 下划线并不改变属性是公用属性的事实, 它只是告诉其他开发者, 应该把该属性看作私有的。

4. 静态作用域

4.1. 静态作用域定义的属性和方法任何时候都能从同一位置访问。在Java中, 类可具有属性和方法, 无需实例化该类的对象, 即可访问这些属性和方法, 例如: java.net.URLEncoder类, 它的函数encode()就是静态方法。

4.2. JavaScript没有静态作用域

4.2.1. 严格来说, JavaScript并没有静态作用域。不过, 它可以给构造函数提供属性和方法。还记得吗, 构造函数只是函数。函数是对象, 对象可以有属性和方法。例如:

function sayHello() {
    alert("hello");
}

sayHello.alternate = function() {
    alert("hi");
}

sayHello();     // 输出"hello"
sayHello.alternate();   // 输出"hi"

4.2.2. 这里, 方法alternate()实际上是函数sayHello的方法。可以像调用常规函数一样调用sayHello()输出"hello", 也可以调用sayHello.alternate()输出"hi"。即使如此, alternate()也是sayHello() 公用作用域中的方法, 而不是静态方法。

5. 关键字this

5.1. this的功能

5.1.1. 在JavaScript中, 要掌握的最重要的概念之一是关键字this的用法, 它用在对象的方法中。关键字this总是指向调用该方法的对象, 例如:

var oCar = new Object;
oCar.color = "red";
oCar.showColor = function() {
  alert(this.color);
};

oCar.showColor();       // 输出"red"

5.1.2. 在上面的代码中, 关键字this用在对象的showColor()方法中。在此环境中, this等于oCar。下面的代码与上面的代码的功能相同:

var oCar = new Object;
oCar.color = "red";
oCar.showColor = function() {
  alert(oCar.color);
};

oCar.showColor();       // 输出"red"

5.2. 使用this的原因

5.2.1. 为什么使用this呢?因为在实例化对象时, 总是不能确定开发者会使用什么样的变量名。使用this, 即可在任何多个地方重用同一个函数。请思考下面的例子:

function showColor() {
    alert(this.color);
};

var oCar1 = new Object;
oCar1.color = "red";
oCar1.showColor = showColor;

var oCar2 = new Object;
oCar2.color = "blue";
oCar2.showColor = showColor;

oCar1.showColor();      // 输出"red"
oCar2.showColor();      // 输出"blue"

5.2.2. 在上面的代码中, 首先用this定义函数showColor(), 然后创建两个对象(oCar1和oCar2), 一个对象的color属性被设置为"red", 另一个对象的color属性被设置为"blue"。两个对象都被赋予了属性showColor, 指向原始的showColor()函数(注意这里不存在命名问题, 因为一个是全局函数, 而另一个是对象的属性)。调用每个对象的showColor(), oCar1输出是"red", 而oCar2的输出是"blue"。这是因为调用oCar1.showColor() 时, 函数中的this关键字等于oCar1。调用oCar2.showColor()时, 函数中的this关键字等于oCar2。

5.2.3. 注意, 引用对象的属性时, 必须使用this关键字。例如, 如果采用下面的代码, showColor()方法不能运行:

function showColor() {
    alert(color);
};

5.2.4. 如果不用对象或this关键字引用变量, JavaScript就会把它看作局部变量或全局变量。然后该函数将查找名为color的局部或全局变量, 但是不会找到。结果如何呢?该函数将在警告中显示"null"。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值