Understanding Irakli’s code ("new" protocol)

Irakli Gozalishvili rfobic at gmail.com
Fri Jun 24 12:48:47 PDT 2011




On Friday, 2011-06-24 at 21:13 , Axel Rauschmayer wrote:

> I’m trying to understand all the implications of Irakli’s code.
> 
> https://gist.github.com/d33befccbe1e0ed492d5
> 
>  Object.prototype.new = function new() {
>  return new this.constructor();
>  };
>  Object.prototype.extend = function extend(properties) {
>  var constructor = new Function(), descriptor = {};
>  properties = properties || {};
>  Object.getOwnPropertyNames(properties).forEach(function(name) {
>  descriptor[name] = Object.getOwnPropertyDescriptor(properties, name);
>  });
>  descriptor.constructor = { value: constructor };
>  return Object.freeze(constructor.prototype = Object.create(this, descriptor));
>  };
> 
>  Object.new = function new() {
>  return Object.prototype.new();
>  };
>  Object.extend = function extend(properties) {
>  return Object.prototype.extend(properties);
>  };
> 
> Questions:
> 
> 1. Do "new" and "extend" really work properly on any built-in other than Object?
>  - E.g., I would expect String.extend() to lead to the invocation of Object.prototype.extend() which assumes "this" to be a prototype, but it is a constructor.
>  - This could be fixed by checking whether "this" is a function and then acting accordingly. Or by setting up a constructor/class method "extend" for each built-in.
I have not tried or thought much about other build-ins as showing idea was a main point. Yeah I was thinking that similar methods could be created per build-ins if necessary.


> 2. I don’t like that new() methods have to keep the result of super.new() and return it. I would prefer something like the code below, which enables a constructor behavior like in Allen’s example.
> 
I personally think that whole prototype, constructor and new keyword relationships add a lot of complexity to a language, and since this was fitting discussion nicely I though I'd share idea how this can be evolved to something more straight forward, that fits language much more IMO. I like new as a method because code is becomes simple and obvious. 

> 3. Are my changes really an improvement or do they impede proper interaction with built-ins, somehow?
> 
> ===== Library code =====
> 
> // Optional, possibly faster: split the method below into Object.prototype.new and Function.prototype.new (the latter overriding the former)
> Object.prototype.new = function new() {
>  if (this instanceof Function) {
>  return new this();
>  } else {
>  return new this.constructor();
>  }
> }; 
> // Performance is less of an issue for this method
> Object.prototype.extend = function extend(properties) {
>  var superProto;
>  if (this instanceof Function) {
>  superProto = this.prototype;
>  } else {
>  superProto = this;
>  }
>  var descriptor = {};
>  properties = properties || {};
>  Object.getOwnPropertyNames(properties).forEach(function(name) {
>  descriptor[name] = Object.getOwnPropertyDescriptor(properties, name);
>  });
>  var thisProto = Object.create(superProto, descriptor);
>  if (thisProto.constructor) {
>  thisProto.constructor.prototype = thisProto;
>  }
>  thisProto.__super__ = superProto;
>  return thisProto;
> };
> 
> // Optional: split the method below into Object.prototype.hasInstance and Function.prototype.hasInstance
> Object.prototype.hasInstance = function extend(instance) {
>  if (this instanceof Function) {
>  return instance instanceof this;
>  } else {
>  return this.isPrototypeOf(instance);
>  }
> };

In my library I just use Foo.isPrototypeOf(bar);
https://github.com/Gozala/selfish

> 
> /**** Not necessary, any more (Object instanceof Object)
> Object.new = function new() {
>  return Object.prototype.new();
> };
> Object.extend = function extend(properties) {
>  return Object.prototype.extend(properties);
> };
> ****/
> 
> ===== Using the library =====
> 
> const SkinnedMesh = THREE.Mesh.extend({
>  constructor: function SkinnedMesh(geometry, materials) {
>  SkinnedMesh.__super__.constructor.apply(this, arguments);
>  // initialize instance properties
>  this.identityMatrix = THREE.Matrix4.new();
>  this.bones = [];
>  this.boneMatrices = [];
>  },
>  update: function(camera) {
>  ...
>  // call base version of same method
>  SkinnedMesh.__super__.update.call(this);
>  }
> });
> _______________________________________________
> es-discuss mailing list
> es-discuss at mozilla.org (mailto:es-discuss at mozilla.org)
> https://mail.mozilla.org/listinfo/es-discuss

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20110624/6880ffd3/attachment-0001.html>


More information about the es-discuss mailing list