从 Aadit M Shah或 Why Prototypal Inheritance Matters阅读一些文章
Stop Using Constructor Functions in JavaScript来自埃里​​克·埃利奥特(Eric Elliott),我认为我理解了所有的观点,在理论上.但实际上我看不到这种模式的真正优势.

我们来看看两个代码片段中的两个实现来继承.

>第一个使用augment.js它是Aadit M Shah的脚本
>在这个例子中,我们将使用this script.由Aadit M Shah也是这样做的.

实施1:

var AugmentPerson = Object.augment(function() {
      this.constructor = function(name) {
          this.name = name;
      };
      this.setAddress = function(country,city,street) {
          this.country = country;
          this.city = city;
          this.street = street;
      };
    });
    var AugmentfrenchGuy = AugmentPerson.augment(function(base) {
      this.constructor = function(name) {
          base.constructor.call(this,name);
      };
      this.setAddress = function(city,street) {
          base.setAddress.call(this,"France",street);
      };
    });
    var AugmentParislover = AugmentfrenchGuy.augment(function(base) {

      this.constructor = function(name) {
          base.constructor.call(this,name);
      };

      this.setAddress = function(street) {
          base.setAddress.call(this,"Paris",street);
      };
    });
    var t = new AugmentParislover("Mary");
    t.setAddress("CH");
    console.log(t.name,t.country,t.city,t.street); //Mary France Paris CH

在这个例子中,我们使用函数构造函数,而不是直接从对象继承.

实施2:

var CreatePerson = {
        create: function (name) {
            this.name = name;
            return this.extend();
        },setAddress: function(country,street) {
             this.country = country;
             this.city = city;
             this.street = street;
        }
    };
    var CreatefrenchGuy  = CreatePerson.extend({
        create: function (name) {
            return CreatePerson.create.call(this,name);
        },setAddress: function(city,street) {
            CreatePerson.setAddress('France',street);
        }
    });
    var CreateParislover  = CreatefrenchGuy.extend({
        create: function (name) {
            return CreatefrenchGuy.create.call(this,setAddress: function(street) {
            CreatefrenchGuy.setAddress('Paris',street);
        }
    });

    var t = CreateParislover.create("Mary");
    t.setAddress("CH");
    console.log(t.name,t.street); //Mary France Paris CH

说实话,我试图看到第二个实现的好处.但我不能.我唯一看到的是更灵活的是因为我们可以使用apply来创建实例:

var t = CreateParislover.create.apply(CreateParislover,[“Mary”]);

这给了我们更多的灵活性,这是真的.但是我们可以对this做同样的事情:

Function.prototype.new = function () {
     function functor() { return constructor.apply(this,args); }
     var args = Array.prototype.slice.call(arguments);
     functor.prototype = this.prototype;
     var constructor = this;
     return new functor;
  };

然后我们可以:

var t = AugmentParislover.new.apply(AugmentParislover,["Mary"]);

在灵活性,可重用性,难度方面真正的好处是什么?
因为如果你检查两种情况的表现. Object.create()几乎比new:http://jsperf.com/inheritance-using-create-vs-new慢得多
我很混乱

解决方法

以前有类似的问题已经被问及了很多次.看到:

Constructor function vs Factory functions
Classical Vs prototypal inheritance

更多学习:
https://medium.com/javascript-scene/3-different-kinds-of-prototypal-inheritance-es6-edition-32d777fa16c9#.s0r3i5w6t
http://vimeo.com/69255635

TL;博士

>构建者打破/封闭的原则
>构造函数将对象创建与对象初始化相结合 – 有时会妨碍代码的可重用性
>构造函数看起来有点像类,这是令人困惑的. JavaScript不需要类(我建议避免ES6中的类关键字). JavaScript有一些比类更好的东西.
>原型委托和动态对象扩展(连接继承)的组合比传统的继承更强大和灵活.
>构造函数.prototype和实例之间的连接在JavaScript中是虚弱的和不可信的.使用构造函数可以提供一个工作实例的幻觉,当它不能在执行上下文中工作时,这可能会令人困惑,或者如果构造函数原型被替换,则不起作用.
使用构造函数更换原型更加困难.您可能想要这样做来启用多态对象构造.使用工厂,热插拔原型很容易,可以使用.call()和.apply()完成.

编辑 – 响应OP发布的“答案”:

Object.create最好的一点是,它是一个专用的低级工具,可以让您创建一个新的对象,并分配您想要的任何原型,而不使用构造函数.有很多理由来避免构建者,这里深入讨论:Constructor function vs Factory functions

>用于演示“较少代码”的代码并不能真正显示古典和原型继承之间的区别.一个更典型的例子可能是:

古典

var Animal = function Animal(name) {
  this.name = name;
};

Animal.prototype.walk = function walk() {
  console.log(this.name + ' goes for a walk.');
};

var Rabbit = function Rabbit(/* name */) {
  // Because construction and instantiation are conflated,you must call super().
  Animal.prototype.constructor.apply(this,arguments);
};

// Classical inheritance is really built on top of prototypal inheritance:
Rabbit.prototype = Object.create(Animal.prototype);

// Fix the .constructor property:
Rabbit.prototype.constructor = Rabbit;

Rabbit.prototype.jump = function jump() {
  console.log(this.name + ' hops around a bit.');
};

var myRabbit = new Rabbit('Bunny George');

myRabbit.walk();
// Bunny George goes for a walk.

原型

var animalMethods =  {
  walk: function walk() {
    console.log(this.name + ' goes for a walk.');
  }
};

var animal = function animal(name) {
  var instance = Object.create(animalMethods);
  instance.name = name;
  return instance;
};

var rabbitMethods = {
  jump: function jump() {
    console.log(this.name + ' hops around a bit.');
  }
};

var rabbit = function rabbit(name) {
  var proto = rabbitMethods;

  // This is more commonly done like mixin({},animalMethods,rabbitMethods);
  // where mixin = $.extend,_.extend,mout.object.mixIn,etc... It just copies
  // source properties to the destination object (first arg),where properties from
  // the last argument override properties from prevIoUs source arguments.
  proto.walk = animalMethods.walk;
  var instance = Object.create(rabbitMethods);

  // This Could just as easily be a functional mixin,// shared with both animal and rabbit.
  instance.name = name;
  return instance;
};

var rabbit2 = rabbit('Bunny Bob');

rabbit2.walk();
// Bunny Bob goes for a walk.

所需的代码量非常相似,但对于我来说,原型更重要的是做得更多,而且它也更灵活,并且没有一个典型的继承关系式的行李.

javascript – 了解为什么真正的原型继承比古典/伪原型继承更好,为什么我不应该使用“新”的更多相关文章

  1. Xcode C开发,需要澄清

    我非常喜欢Xcode提供对该语言可能的成员函数的深入了解的方式,并且更喜欢相对于文本伙伴使用它,如果不是因为我今天注意到的奇怪.当strings=“Teststring”时;唯一可用的substr签名如图所示但据我所知,签名应该是什么iseeonline确实s.substr(1,2);既被理解也适用于Xcode.当我尝试方法完成时为什么不显示?

  2. xamarin.ios – 没有找到ViewController ::.ctor(System.IntPtr)的构造函数

    我有一个问题,我的Monotouch应用程序有时在收到内存警告后才会崩溃.请参见下面的堆栈跟踪.堆栈跟踪是正确的,因为指定的类缺少构造函数获取IntPtr参数.但是这是有意的,因为我在应用程序中根本不使用InterfaceBuilder.那为什么会这样呢?

  3. ios – Swift – NSURL错误

    尝试使用下面的NSURL类时出错,下面的代码实际上是试图将我从Facebook拉入的图像存储到imageView中.错误如下:不知道为什么会这样,帮忙!解决方法你正在调用的NSURL构造函数有这个签名:?表示构造函数可能不返回值,因此它被视为可选.NSData构造函数也是如此:快速解决方法是:最好的解决方案是检查(解包)这些选项,即使您确定它们包含值!

  4. 如何在Xcode中追踪“libc abi.dylib:纯虚函数!”

    我有一个多线程OSX应用程序,它使用C,Objective-C和Swift的混合.当我的应用程序关闭时,我在Xcode调试器窗口中看到了这一点:我知道这个错误通常是由对C类构造函数或析构函数中的虚函数的调用引起的.有没有一种简单的方法可以找到它的位置?

  5. Swift实现对象归档

    Swift实现对象归档时有几个注意点要继承NSCoding,实现两个方法extension是一个分类,分类不允许有存储能力,所以协议方法不能写在分类中协议中的init(coderdecoder:NSCoder)函数会覆盖原始的构造函数,所以类中至少还要有另一个init方法如果不指定键名,会使用属性名称作为key,基本数据类型,需要指定key

  6. 【Swift初见】Swift构造过程

    构造过程是通过构造器来实现的,其实每个构造器就可以看作是一个函数,只是这个函数是为了执行初始化的。每个类都必须拥有一个指定构造器。

  7. swift的struct结构体类型介绍使用

  8. swift struct

    //:Playground-noun:aplacewherepeoplecanplayimportCocoavarstr="Hello,playground"structpoint{varx=0;vary=init(x:Int,y:Int){self.x=x;y=y;println("init");}funcgetCenter()->Int{return(x+y)/2;}mutatingfunca

  9. 《The Swift Programming Language》2.0版之自动引用计数

    Swift1.0文档翻译:TimothyYeSwift1.0文档校对:HawsteinSwift2.0文档校对及翻译润色:ChannePS:之前1.0版中文版看不懂地方在对比英文版后就懂了,还是之前翻译的不够准确啊。,而不是Person),它们的值会被自动初始化为nil,目前还不会引用到Person类的实例。由于Person类的新实例被赋值给了reference1变量,所以reference1到Person类的新实例之间建立了一个强引用。在你将john和number73赋值为nil后,强引用关系如下图:P

  10. swift #6 类

随机推荐

  1. js中‘!.’是什么意思

  2. Vue如何指定不编译的文件夹和favicon.ico

    这篇文章主要介绍了Vue如何指定不编译的文件夹和favicon.ico,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

  3. 基于JavaScript编写一个图片转PDF转换器

    本文为大家介绍了一个简单的 JavaScript 项目,可以将图片转换为 PDF 文件。你可以从本地选择任何一张图片,只需点击一下即可将其转换为 PDF 文件,感兴趣的可以动手尝试一下

  4. jquery点赞功能实现代码 点个赞吧!

    点赞功能很多地方都会出现,如何实现爱心点赞功能,这篇文章主要为大家详细介绍了jquery点赞功能实现代码,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

  5. AngularJs上传前预览图片的实例代码

    使用AngularJs进行开发,在项目中,经常会遇到上传图片后,需在一旁预览图片内容,怎么实现这样的功能呢?今天小编给大家分享AugularJs上传前预览图片的实现代码,需要的朋友参考下吧

  6. JavaScript面向对象编程入门教程

    这篇文章主要介绍了JavaScript面向对象编程的相关概念,例如类、对象、属性、方法等面向对象的术语,并以实例讲解各种术语的使用,非常好的一篇面向对象入门教程,其它语言也可以参考哦

  7. jQuery中的通配符选择器使用总结

    通配符在控制input标签时相当好用,这里简单进行了jQuery中的通配符选择器使用总结,需要的朋友可以参考下

  8. javascript 动态调整图片尺寸实现代码

    在自己的网站上更新文章时一个比较常见的问题是:文章插图太宽,使整个网页都变形了。如果对每个插图都先进行缩放再插入的话,太麻烦了。

  9. jquery ajaxfileupload异步上传插件

    这篇文章主要为大家详细介绍了jquery ajaxfileupload异步上传插件,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

  10. React学习之受控组件与数据共享实例分析

    这篇文章主要介绍了React学习之受控组件与数据共享,结合实例形式分析了React受控组件与组件间数据共享相关原理与使用技巧,需要的朋友可以参考下

返回
顶部