Note that there are some explanatory texts on larger screens.

plurals
  1. POObject.create Prototype Chains
    primarykey
    data
    text
    <h1>Initial Question</h1> <p>Yesterday i read about ECMAScript 5 Object.create() And I wanted to start building prototype Chains in my Code with this method instead of setting the prototype and its constructor, I like that you can directly set writable configurable etc.. </p> <p>I tried it like this</p> <pre><code>function printobject(msg, obj) { if (msg) { document.write("&lt;b&gt;" + msg + "&lt;/b&gt;&lt;br&gt;"); document.write("&lt;hr&gt;&lt;br&gt;"); } for (var prop in obj) { if (obj.hasOwnProperty(prop)) { if (obj[prop].toString() !== "[object Object]") { document.write(prop + " : " + obj[prop] + "&lt;br&gt;"); } else { document.write("&lt;b&gt;" + prop + " : " + obj[prop] + "&lt;/b&gt;&lt;br&gt;"); printobject("", obj[prop]); } } } if (msg) { document.write("&lt;br&gt;&lt;hr&gt;&lt;br&gt;"); } }; var base = { extend: function () { //extend this Object var args = Array.prototype.slice.call(arguments); printobject("Arguments to Extend", args) var that = Object.create(this, (args ? args.shift() : {})); var arg = args.shift() || {}; printobject("Copy Properties to New Object", arg); for (var prop in arg) { that[prop] = arg[prop]; } // Object.freeze(that); return that; }, create: function () { //Creates new instances of the Object var that = Object.create(this, { extend: { value: null, writable: false, configurable: false }, //sets extend and create to null so you cant create a new instance when used create ( use extend instead); create: { value: null, writable: false, configurable: false } }); that.init.apply(that, arguments); //call init function for the new created object; return that; }, init: function () { printobject("No Initfunction supplied for New Object", this); } // Empty init function for fallback } var Human = base.extend({ name: { value: "test" } }, { init: function (name) { alert(name + " has been created"); this.name = name; }, walk: function () { alert(this.name + " walks"); } }); var Human1 = Human.create("test2"); //alert("Human1 - Name:" + Human1.name); Human1.walk(); Human.walk = function () { alert("Walk has been overwritten") }; //Object freezed Human1.walk(); Human1.create = function () { alert("Overwrite create"); }; //Doesnt exist in created Object Human1.create(); ? </code></pre> <ul> <li>Do the methods given in <code>Human</code> only exist once in the ram? and <code>Human1.walk()</code> points to it?</li> <li>I wonder if this is the right Approach of doing it like this? I'm relatively new to JavaScript.</li> </ul> <p>This is the code on <a href="http://jsfiddle.net/2VdJN/" rel="nofollow noreferrer"><strong>jsfiddle</strong></a>.</p> <h2>Answer</h2> <p>First of all, thx a lot that made things def clearer =) But, 1: when I do it like this the instances inherit from their constructor's prototype (?)</p> <pre><code> Nothing = {}; function base() { this.inherit = function(constructor) { alert("inherit"); var obj = constructor; obj.constructor = constructor; obj.prototype = this; return obj ; } ;} base.prototype = Nothing; base.constructor = base; var Top = new base(); var Human = Top.inherit(function(name) { this.name = name; }); var Paul = new Human("Paul"); alert(Paul.name); alert(Paul instanceof Human); //true ` </code></pre> <p>2: So the instanceof operator doesnt break in this Code , (that it works for functions only seems clear to me)</p> <p>But written this way, Paul still inherits the inherit() method from Top's prototype and i would need to overwrite it But if i dont want the instance of Human to inherit the method, how do i do this ?</p> <p>And i cant set property descriptors like wrtable except using Objkect.defineproperty (?) </p> <p>So what are the main benefits from using Object.create() to inherit from Objects vs Setting the prototypes and construcotrs ? =)</p> <p>3: Oh thx, yes thats def right thats not an extension of base object =) thx for the suggestion =)</p> <p>Thx for all the effort =)</p> <h3>Answer</h3> <p>Ok so when i do </p> <blockquote> <p>Nothing = {}</p> <p>base.prototype = Nothing;</p> </blockquote> <p>this doesnt prevent s.o to go up the prototype chain til Object.prototype ? if not , is there a way to do this ? =) Would ( Object.create(null); ) do this,</p> <p>and i thought that i had to set </p> <blockquote> <p>base.prototype.constructor = base;</p> </blockquote> <p>because otherwise, the prototypes constructor of</p> <blockquote> <p>var Top = new base();</p> </blockquote> <p>would be Nothings' or does'nt base inherit a constructor from somewhere up the prototype chain if the prototype is set to Nothing -> </p> <blockquote> <p>Top instanceof base // false </p> </blockquote> <h1>Update</h1> <p>I ended up doing it in a way like this now:</p> <pre><code>var base = { // a tiny little selfmade prototypical inheritance system // you are free to add function arguments for extending the created objects // neither instanceof nor .constructor is featured, because "classes" are no functions create: function(extension,desc) { // instances inherit from the proto objects var newInst = Object.create(this.proto, desc); if(this.proto.childExtendable) //if Subclass allows its Children to be Extendible, do so newInst.extend(extension); if(newInst.init||this.proto.init) //4 newInst.init() return newInst }, inherit: function(props) { // the "class" inherits static methods from the class var sub = Object.create(this); // and the proto objects inherits from the parent proto sub.proto = Object.create(this.proto); props.protect = this.protect; if(props.childExtendable) props.extend = this.extend; this.extend.call(sub.proto, props); return sub; }, extend: function (props) { for (var prop in props) { var propmatch = prop.match(/(.*?)__(.{1,5}?)__(.*)/)||["",prop,"",""]; this[propmatch[1]+propmatch[3]] = props[prop]; if(propmatch[2]) this.protect(propmatch[1]+propmatch[3],propmatch[2]); } }, protect: function(prop,flags) { //with each call it toggles the given flags, so you can protect funcitons given to the inherit function ;; //This should be available to all childs, but adding it to the base.proto, it changes Object.prototyppe ( therefore not a good idea) var d = Object.getOwnPropertyDescriptor(this, prop); if (flags.match(/w/)){ Ti.API.info("Setting writable for propertie " + prop + " in Object " + this + " to " + !d.writable); Object.defineProperty(this, prop, {writable:!d.writable});}; if (flags.match(/c/)){ Ti.API.info("Setting configurable for propertie " + prop + "in Object " + this); Object.defineProperty(this, prop, {configurable:!d.configurable});}; if (flags.match(/e/)){ Ti.API.info("Setting enumerable for propertie " + prop + "in Object " + this); Object.defineProperty(this, prop, {configurable:!d.enumerable});}; if (flags.match(/a/)){ Ti.API.info("Setting enumerable for propertie " + prop + "in Object " + this); Object.preventExtensions(this);}; }, init: function() {}, proto: Object.prototype // or null, if you want }; var Human = base.inherit({ //will be put in Human.proto childExtendable:true, init:function() {alert("Humans Init for all Instances")}, say:function() { alert("Hi, I'm "+this.name); } }); Human.proto.name = "default"; // You could use an argument to the inherit function // I just want to make clear what happens Ti.API.info(Object.getPrototypeOf(Function) + "a"); var paul = Human.create({ //extends this object name: "Paul", test: function() {alert("test")}, init__wce__: function() {alert("Pauls Own Init")}, say__w__ : function() { alert("Hi, I'm" + this.name + "s Own Function")} }); paul.name = "Paul"; // and again, the create function might do it for you paul.say = function() {alert("Pauls say is overwritten")} // define init without __wce__ and it will be overwritten paul.say(); // -&gt; "Hi, I'm Paul" </code></pre> <p>Just if anyone cares<br> However, jsfiddle won't run this, Titanium does everythign as expected maybe some strict mode (??) </p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload