Javascript继承理念(第2部分) [英] Javascript inheritance idea (part 2)

查看:104
本文介绍了Javascript继承理念(第2部分)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

好吧,我第一次试图解释我在做什么的尝试失败了。我基本上复制了Crockford的Object.create(),除了私有变量。

Okay, my first attempt at trying to explain what I was doing failed miserably. I'm basically copying Crockford's Object.create(), except with private variables.

如果你看一下这里接受的答案如何从javascript中继承类?,你会看到Object.create是最后一个模式,我认为更适合Javascript(对象beget对象)的原型性质,而不是模仿经典继承(类beget对象)。

If you look at the accepted answer here How to inherit from a class in javascript?, you will see Object.create as the last pattern, which I think better fits the prototypal nature of Javascript (objects beget objects) instead of emulating classical inheritance (classes beget objects).

如果你看一下维基百科关于原型编程的文章( http://en.wikipedia.org/wiki/Prototype-based_programming ),你可以看到更多我的意思。

If you look at Wikipedia's article on prototype based programming (http://en.wikipedia.org/wiki/Prototype-based_programming), you can see more of what I mean.

Object.create()的缺点是不支持私有成员。这就是我的建议:

The drawback with Object.create() though is that there is no support for private members. This is what I propose:

Function.prototype.from = function(obj) {
    function F() {this.parent = Object(obj);}
    F.prototype = obj;
    var out = new F();
    this.apply(out);
    return out;
};

然后,您可以这样创建对象:

Then, you create objects as thus:

// Create an object
var a = function() {
    var private_property = 'blue';
    this.public_property = 7;

    this.public_method = function() {
        alert(this.public_property + ' ' + private_property);
    }
}.from(null); // .from() works too, but .from(null) is more revealing


// Create a new object using 'a' as the prototype
var b = function() {
    var private_property = 'red';
    this.public_property = 8;
}.from(a);


// See the results
a.public_method(); // Alerts '7 blue'
b.public_method(); // Alerts '8 blue' - Parent methods use parent private variables

a.public_method = function() { alert('rabbit'); };

a.public_method(); // Alerts 'rabbit'
b.public_method(); // Alerts 'rabbit'

b.public_method = function() { alert('dog'); };

a.public_method(); // Alerts 'rabbit'
b.public_method(); // Alerts 'dog' - Parent method is overwritten

我做来自功能的方式是这样当父对象更改其方法时,如果要阻止更改子实例,可以指定:

The way I made the "from" function is such that when a parent object changes its methods, if you want to prevent the change in a child instance, you can specify:

this.public_method = this.parent.public_method;

< strike>请注意,从nihilo创建的对象不会从Object继承(hasOwnProperty等等)。您必须明确指定为.from(Object)。

此模式的好处:


  1. 每个新实例都不浪费内存

  2. 它遵循 true 原型继承模式

  3. 您可以使用this.parent访问父对象(此.__ proto__是浏览器特定的)

  4. 现在存在私有变量

  1. Memory is not wasted for each new instance
  2. It adheres to a true prototypal inheritance pattern
  3. You have access to the parent object using this.parent (this.__proto__ is browser specific)
  4. Private variables now exist

我可以想到这个方法有一个主要缺点:'function()'语法可能会让人们误以为函数被分配给变量而不是对象。

There is one major drawback of this method that I can think of: the 'function()' syntax may confuse people into thinking a function is assigned to the variable instead of an object.

我的问题是,我还有其他缺点吗? (不要包括原型模式的缺点 - 这是主观的 - 但仅限于我的实现)。

My question is, are there other drawbacks that I am missing? (Don't include drawbacks of the prototypal pattern--that's subjective--but only of my implementation).

推荐答案

首先,如前所述, Function.prototype 方法真的很痛苦。为什么不实现这样的事情:

First, as already mentioned, the Function.prototype approach is really a pain. Why not implement the same thing like this:

Object.createChild = function(obj, constructor) {
    function F() { this.parent = Object(obj); }
    F.prototype = obj;
    var out = new F();
    if (typeof constructor == 'function') {
        constructor.apply(out);
    }
    return out;
};

然后使用

var a = Object.createChild(null, function () { /*...*/ });
var b = Object.createChild(a, function () { /*...*/ });

与上述结果相同。
额外奖励:您可以省略构造函数参数,如下所示:

with the same results as above. Bonus: You can omit the constructor argument, like this:

var c = Object.createChild(anything);






其次,我不知道是否有任何用于真正的原型继承,就像你所说的那样。在现实生活中,我非常确定构造函数特别适合于即将扩展的对象( a )。因此,你最终会打电话


Second, I don't know if there's any use for true prototypal inheritance, as you call it. In real life, I'm pretty sure the constructor function is particularly tailored to the object that's about to be extended (a). Thus, you're gonna end up calling

var x = f.from(a);
var y = f.from(a);

f - 一个组合一遍又一遍。是的,与类驱动的方法相比,你节省了一些字节的内存,但老实说,谁在乎呢?

with the very same f-a combination over and over again. And yes, you save some bytes of memory as compared to a class-driven approach, but honestly, who cares?

尽管如此,整个事情真是个好主意理论。

Still, the whole thing is a really good idea in theory.

这篇关于Javascript继承理念(第2部分)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆