js策略模式的疑惑



 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

jquery javascript闭包 JavaScript javascript面向对象

东方馅挂炒面 9 years, 5 months ago

看代码:


 Bonus.prototype.setStrategy=function(strategy){
    this.strategy=strategy;
}
Bonus.prototype.getBonus=function(){
    //这里的calculate是另外三个对象原型下的方法这为什么不报错,是怎么实现的
    return this.strategy.calculate(this.salary);
}

为什么这里没报错,因为你 bonus.setStrategy(new performanceS());传入了performanceS的实例对象,
this.strategy的值就是performanceS的实例对象当然可以使用其原型下的calculate()方法,所以没报错。

涉及知识点 原型链 ,函数创建的时候会自动创建的,自己找相关资料看看就知道怎么回事了

小虎搬运工 answered 9 years, 5 months ago

简单直白一点儿就是,这就是 js 用类创建对象的方式,可以把 performance 看成是类名,然后 new performace 就是这个类生成的对象。

var a = new performance ,具体细节(简化的)是:

  1. 创建一个对象, obj

  2. obj.[[prototype]] = perfomance.prototype ; // 这个属性原本不可以用 js 访问,后来 w3c 把它添加到了标准中,后来使用了新的接口所以又去掉了,但是在 firefox 和 chrome 实现也保留了这个属性叫做 __proto__ ,你可以在他们的调试窗口看到。

  3. this = obj ,然后执行 perfomance 中定义的代码;

  4. 假设上一步 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

大海全是水 answered 9 years, 5 months ago

Your Answer