javascript行为委托

类是一种可选(而不是必须)的设计模式,而且在 JavaScript 使用这样的 [[Prototype]] 语言中实现类是很别扭的,它会存在很多的缺点,列如:繁琐杂乱的 .prototype引用、试图调用原型链上层同名函数时的显式伪多态以及不可靠、不美观而且容易被误解成“构造函数”的 .constructor 。

除此之外,类设计还存在更加深刻的问题。传统面向类的语言中父类和子 类、子类和实例之间其实是复制操作,但是在 [[Prototype]] 中并没有复制,相反,它们之间只有委托关联。

先看一段代码:

    var Task = {
        setId: function (ID) {
            this.id = ID
        },
        outputID: function () {
            console.log(this.id)
        }
    };
    var XYZ = Object.create(Task);
    XYZ.prepareTak = function (ID, Label) {
        this.setID(ID);
        this.label = Label
    }
    XYZ.outputTaskDetails = function () {
        this.outputID();
        console.log(this.label)
    }
    var ABC = Object.create(Task)
    ......

复制代码

在这段代码中,Task和XYZ并不是类,他们只是对象。A通过Object.create(...)创建,它的[[Prototype]]委托了Task对象。

委托行为意味着某些对象(XYZ)在找不到属性或者方法引用时会把这个请求委托给另一个对象。

比较

首先是典型的(“原型”)面向对象风格

    function Foo(who) {
        this.me = who;
    }
    Foo.prototype.identify = function() {
        return "I am " + this.me;
    };
    function Bar(who) {
        Foo.call( this, who );
    }
    Bar.prototype = Object.create( Foo.prototype );
    Bar.prototype.speak = function() {
        alert( "Hello, " + this.identify() + "." );
    };
    var b1 = new Bar( "b1" );
    var b2 = new Bar( "b2" );
    b1.speak();
    b2.speak();
复制代码

子类 Bar 继承了父类 Foo ,然后生成了 b1 和 b2 两个实例。 b1 委托了 Bar.prototype ,后者 委托了 Foo.prototype 。

    Foo = {
        init: function(who) {
            this.me = who;
        },
        identify: function() {
            return "I am " + this.me;
        }
    };
    Bar = Object.create( Foo );
    Bar.speak = function() {
        alert( "Hello, " + this.identify() + "." );
    };
    var b1 = Object.create( Bar );
    b1.init( "b1" );
    var b2 = Object.create( Bar );
    b2.init( "b2" );
    b1.speak();
    b2.speak();
复制代码

我们用对象关联的方式同样实现了上述的逻辑,但重要的一点是这段代码简洁了许多,我们只是把对象关联了起来,并不需要那些令人困惑又难受的模仿类的行为(如构造函数、new);

JavaScript 中的函数之所以可以访问 call(..) 、 apply(..) 和 bind(..),就是因为函数本身是对象。而函数对象同样有 [[Prototype]] 属性并且关联到 Function.prototype 对象,因此所有函数对象都可以通过委托调用这些默认方法。

对象关联是一种编码风格,它倡导的是直接创建和关联对象,不把它们抽象成类。对象关联可以用基于 [[Prototype]] 的行为委托非常自然地实现。

转载于:https://juejin.im/post/5c4ea2a36fb9a049a5714acf

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值