var performanceS=function(){};
performanceS.prototype.calculate=function(salary){
return salary*4;
}
var performanceA=function(){};
performanceA.prototype.calculate=function(salary){
return salary*3;
}
var performanceB=function(){};
performanceB.prototype.calculate=function(salary){
return salary*2;
}
var Bonus=function(){
this.salary=null;
this.strategy=null;
};
Bonus.prototype.setSalary=function(salary){
this.salary=salary;
}
Bonus.prototype.setStrategy=function(strategy){
this.strategy=strategy;
}
Bonus.prototype.getBonus=function(){
//这里的calculate是另外三个对象原型下的方法这为什么不报错,是怎么实现的
return this.strategy.calculate(this.salary);
}
var bonus=new Bonus();
bonus.setSalary(10000);
bonus.setStrategy(new performanceS());
console.log(bonus.getBonus());//40000
bonus.setStrategy(new performanceA());
console.log(bonus.getBonus());//30000
简单直白一点儿就是,这就是 js 用类创建对象的方式,可以把
performance
看成是类名,然后new performace
就是这个类生成的对象。var a = new performance
,具体细节(简化的)是:创建一个对象,
obj
obj.[[prototype]] = perfomance.prototype
; // 这个属性原本不可以用 js 访问,后来 w3c 把它添加到了标准中,后来使用了新的接口所以又去掉了,但是在 firefox 和 chrome 实现也保留了这个属性叫做__proto__
,你可以在他们的调试窗口看到。令
this = obj
,然后执行perfomance
中定义的代码;假设上一步
perfomamce
的返回值是'ret'。 如果ret
是对象,那么a = ret
, 否则a = obj
;然后就是访问
a
的属性(读取,先不谈写入)的时候,给出一个属性,calculate
,首先看a.calculate
是否存在,如果不存在就试图访问a.[[prototype]].calculate
,如果还不存在就访问a.[[prototype]].calculate
。。。。这就是 js 的原型链,自己百度找其他参考资料(为什么有人一次又一次的问这个问题)
所以你的代码就是
a.calculate
就是a.[[prototype]].calculate
也就是perfomance.prototype.calculate
具体可以参考 ecma-262 不过写的比较不容易懂
http://ecma-international.org/publications/standards/Ecma-262.htm