在 PHP 中,有这样三个类:妻子、丈夫和银行。
妻子和丈夫各有三个属性,分别是性别、拥有的钱,以及各自不同的方法。
妻子的方法是每个月把丈夫挣到的钱收起来,丈夫则每个月把钱交给妻子。
剩下的一个银行类,有一个资产属性和一个交钱的方法,不过这里的“交钱”只是为了方便演示类型控制。
在 PHP 中,我们可以这样定义这三个类:
<?php
class Wife{
public $sex="female";
public $money=10000;
public function savemoney($people){
$this->money += $people->handed(1000);
}
}
class Husband{
public $sex="male";
public $money=10000;
public function handed($num){
$this->money -= $num;
return $num;
}
}
class Bank{
public $money=100000000;
public function handed($num){
$this->money -=$num;
return $num;
}
}
我们知道,丈夫的钱上交给妻子,这是理所当然的。
但是,上面的程序存在一个问题:银行的钱也可以交给妻子。
<?php
$she=new Wife();
$he=new Husband();
$ccb=new Bank();
$she->savemoney($he);
echo $she->money, "<br/>";
echo $he->money;
// 接下来看看妻子能不能接受银行的上交
$she->savemoney($ccb);
echo $she->money;
echo $ccb->money;
这样的话,妻子俨然成了“抢劫犯”。
显然,这在实际程序中是不合理的。
那么,如何阻止这种情况发生呢?
PHP中的类型控制
PHP 提供了类型声明,我们可以在 savemoney() 方法的参数中指定接收的对象必须是 Husband 类型:
class Wife{
public $sex = "female";
public $money = 10000;
public function savemoney(Husband $people){
$this->money += $people->handed(1000);
}
}这样,当再次执行 $she->savemoney($ccb);
PHP 就会提示参数类型错误,因为这里传入的是 Bank 对象,而方法要求的是 Husband 对象。
这样,就可以很好地解决参数类型的问题。
JavaScript中怎么做?
那么在 JavaScript 中,如果也想做类似的控制,应该怎么办?
先看一下没有进行类型判断时的代码。
functionWife(){
this.sex ="female";
this.money =10000;
this.savemoney =function(people){
this.money +=people.handed(1000);
};
}
function Husband(){
this.money =10000;
this.sex ="male";
this.handed =function(num){
this.money -=num;
return num;
};
}
functionBank(){
this.money =100000000;
this.handed =function(num){
this.money -=num;
return num;
};
}
var she=newWife();
var he=newHusband();
var ccb=newBank();
she.savemoney(he);
console.log(she.money);
console.log(he.money);
she.savemoney(ccb);
console.log(she.money);
console.log(ccb.money);可以看到,在这个例子中 she.savemoney(he) 能够正常执行。
但是 she.savemoney(ccb) 同样也能够执行。
因为 JavaScript 不会像 PHP 一样,在这里直接声明:
savemoney()必须接收一个Husband对象。
那么,这时候应该怎么做?
其实很简单,我们只需要判断传入的对象是不是 Husband 的实例即可。
JavaScript 提供了 instanceof 运算符,可以用来判断一个对象的原型链上是否存在指定构造函数的 prototype。
使用instanceof进行判断
可以把 Wife 改成:
function Wife(){
this.sex ="female";
this.money =10000;
this.savemoney = function(people){
if(!(peopleinstanceofHusband)){
throw new TypeError(
"Type error: people must be an instance of Husband"
);
}
this.money +=people.handed(1000);
};
}这样:
var she=newWife();
var he=newHusband();
var ccb=newBank();
she.savemoney(he);
可以正常执行。但是 she.savemoney(ccb) 就会抛出类型错误.
也就是说,我们通过 people instanceof Husband
判断传入的 people 是否是 Husband 的实例。
如果不是,就不允许继续执行。
PHP和JavaScript的区别
通过上面的例子可以看出来,PHP 和 JavaScript 都可以对传入的对象进行一定程度的类型控制,但是实现方式并不一样。
PHP 可以直接在参数中声明:
而 JavaScript 则需要在函数内部主动进行判断:
所以,在 JavaScript 中,如果我们希望一个函数只能接受某一类对象,就可以利用 instanceof 进行判断。
不过需要注意,instanceof 判断的并不是“这个对象里面有没有某几个属性”,而是检查对象的原型链与指定构造函数的 prototype 之间是否存在对应关系。
对于刚开始学习 JavaScript 对象和继承的人来说,理解这一点还是比较重要的。
评论0
欢迎分享你的看法,也欢迎补充不同的实践经验。