|
561 | 561 | var child = Y.Object(parent); |
562 | 562 | }); |
563 | 563 |
|
564 | | -<a name="a20"></a> |
565 | 564 | ## 通过复制属性继承 |
566 | 565 |
|
567 | | -让我们来看一下另外一种继承模式——通过复制属性继承。在这种模式中,一个对象通过简单地复制另一个对象来获得功能。下面是一个简单的实现这种功能的extend()函数: |
| 566 | +让我们来看一下另外一种继承模式——通过复制属性继承。在这种模式中,一个对象通过简单地复制另一个对象来获得功能。下面是一个简单的实现这种功能的`extend()`函数: |
568 | 567 |
|
569 | 568 | function extend(parent, child) { |
570 | 569 | var i; |
|
574 | 573 | child[i] = parent[i]; |
575 | 574 | } |
576 | 575 | } |
577 | | - return child; |
| 576 | + return child; |
578 | 577 | } |
579 | 578 |
|
580 | | -这是一个简单的实现,仅仅是遍历了父对象的成员然后复制它们。在这个实现中,child是可选参数,如果它没有被传入一个已有的对象,那么一个全新的对象将被创建并被返回: |
| 579 | +这是一个简单的实现,仅仅是遍历了父对象的成员然后复制它们。在这个实现中,`child`是可选参数,如果它没有被传入一个已有的对象,那么一个全新的对象将被创建并返回: |
581 | 580 |
|
582 | 581 | var dad = {name: "Adam"}; |
583 | 582 | var kid = extend(dad); |
584 | 583 | kid.name; // "Adam" |
585 | 584 |
|
586 | | -上面给出的实现叫作对象的“浅拷贝”(shallow copy)。另一方面,“深拷贝”是指检查准备复制的属性本身是否是对象或者数组,如果是,也遍历它们的属性并复制。如果使用浅拷贝的话(因为在JavaScript中对象是按引用传递),如果你改变子对象的一个属性,而这个属性恰好是一个对象,那么你也会改变父对象。实际上这对方法来说可能很好(因为函数也是对象,也是按引用传递),但是当遇到其它的对象和数组的时候可能会有些意外情况。考虑这种情况: |
| 585 | +上面给出的实现叫作对象的“浅拷贝”(shallow copy),与之相对,“深拷贝”是指检查准备复制的属性本身是否是对象或者数组,如果是,也遍历它们的属性并复制。如果使用浅拷贝的话(因为在JavaScript中对象是按引用传递),如果你改变子对象的一个属性,而这个属性恰好是一个对象,那么你也会改变父对象。实际上这对方法来说可能很好(因为函数也是对象,也是按引用传递),但是当遇到其它的对象和数组的时候可能会有些意外情况。考虑这种情况: |
587 | 586 |
|
588 | 587 | var dad = { |
589 | 588 | counts: [1, 2, 3], |
|
594 | 593 | dad.counts.toString(); // "1,2,3,4" |
595 | 594 | dad.reads === kid.reads; // true |
596 | 595 |
|
597 | | -现在让我们来修改一下extend()函数以便做深拷贝。所有你需要做的事情只是检查一个属性的类型是否是对象,如果是,则递归遍历它的属性。另外一个需要做的检查是这个对象是真的对象还是数组。我们可以使用第3章讨论过的数组检查方式。最终深拷贝版的extend()是这样的: |
| 596 | +现在让我们来修改一下`extend()`函数以便实现深拷贝。你需要做的事情只是检查一个属性的类型是否是对象,如果是,则递归遍历它的属性。另外一个需要做的检查是这个对象是真的对象还是数组,可以使用第三章讨论过的数组检查方式。最终深拷贝版的`extend()`是这样的: |
598 | 597 |
|
599 | 598 | function extendDeep(parent, child) { |
600 | 599 | var i, |
|
633 | 632 | kid.reads.web = true; |
634 | 633 | dad.reads.paper; // true |
635 | 634 |
|
636 | | -通过复制属性继承的模式很简单且应用很广泛。例如Firebug(JavaScript写的Firefox扩展)有一个方法叫extend()做浅拷贝,jQuery的extend()方法做深拷贝。YUI3提供了一个叫作Y.clone()的方法,它创建一个深拷贝并且通过绑定到子对象的方式复制函数。(本章后面将有更多关于绑定的内容。) |
| 635 | +通过复制属性继承的模式很简单且应用很广泛。例如Firebug(JavaScript写的Firefox扩展)有一个方法叫`extend()`做浅拷贝,jQuery的`extend()`方法做深拷贝。YUI3提供了一个叫作`Y.clone()`的方法,它创建一个深拷贝并且通过绑定到子对象的方式复制函数。(本章后面将有更多关于绑定的内容。) |
637 | 636 |
|
638 | 637 | 这种模式并不高深,因为根本没有原型牵涉进来,而只跟对象和它们的属性有关。 |
639 | 638 |
|
640 | | -<a name="a21"></a> |
641 | 639 | ## 混元(Mix-ins) |
642 | 640 |
|
643 | 641 | 既然谈到了通过复制属性来继承,就让我们顺便多说一点,来讨论一下“混元”模式。除了前面说的从一个对象复制,你还可以从任意多数量的对象中复制属性,然后将它们混在一起组成一个新对象。 |
|
665 | 663 | {sugar: "sure!"} |
666 | 664 | ); |
667 | 665 |
|
668 | | -图6-10展示了在Firebug的控制台中用console.dir(cake)展示出来的混元后cake对象的属性。 |
| 666 | +图6-10展示了在Firebug的控制台中用`console.dir(cake)`展示出来的混元后`cake`对象的属性。 |
669 | 667 |
|
670 | 668 |  |
671 | 669 |
|
672 | 670 | 图6-10 在Firebug中查看cake对象 |
673 | 671 |
|
674 | | -> 如果你习惯了某些将混元作为原生部分的语言,那么你可能期望修改一个或多个父对象时也影响子对象。但在这个实现中这是不会发生的事情。这里我们只是简单地遍历、复制自己的属性,并没有与父对象的链接。 |
| 672 | +> 如果你习惯了某些将混元作为原生部分的语言,那么你可能期望修改一个或多个父对象时也影响子对象。但在这个实现中这是不会发生的事情。这里我们只是简单地遍历、复制自有属性,并没有与父对象有任何链接。 |
675 | 673 |
|
676 | 674 | <a name="a22"></a> |
677 | 675 | ## 借用方法 |
|
0 commit comments