使用_uproto的简单javascript委托__

使用_uproto的简单javascript委托__,javascript,inheritance,prototype,Javascript,Inheritance,Prototype,我已经习惯了Java,所以当我尝试这样做时: function subSection(pattern){ this.total = 0; this.pattern = pattern; this.distance=0; } function enhancer(pattern){ __proto__:subSection; this.pattern = pattern; } function silencer(pattern){ __proto_

我已经习惯了Java,所以当我尝试这样做时:

function subSection(pattern){
    this.total = 0;
    this.pattern = pattern;
    this.distance=0;
}

function enhancer(pattern){
    __proto__:subSection;
    this.pattern = pattern;
}

function silencer(pattern){
    __proto__:subSection;
    this.pattern = pattern;
}

var a = new enhancer("aaa");
document.write(a.distance)
    //create Enhancer object
function Enhancer(pattern){
    this.subSection(pattern);    
}

//extend Enhancer with object methods
Enhancer.prototype = {

   subSection: function(pattern){
         this.pattern = pattern;
         this.total = 0;        
         this.distance=0;
  }

};
我得到“未定义”。我认为我继承了成员不使用的total和distance数据,这是Mozilla的专有属性(被其他一些人复制),已被弃用。分配给construtor.prototye

该行:

> __proto__:subSection;
没有将任何内容分配给任何内容,它是一个标签(
\uuuuu proto\uuuuu
),后跟一条语句
subSection
,该语句是对未分配给任何内容的subSection函数的引用

你似乎不理解原型继承,试试道格拉斯·克罗克福德的

以下可能与您正在尝试做的类似,这里肯定有一千个类似的问题:

function SubSection(pattern) {
    this.pattern = pattern;
    this.total = 0;
    this.distance=0;
}

// Add a method to subSection.prototype
SubSection.prototype.getDistance = function() {
  return this.distance;
}

function Enhancer(pattern) {
    this.pattern = pattern;
}

// To make enhancer inherit from subSection, make its prototype
// an instance of subSection
Enhancer.prototype = new SubSection();

var a = new Enhancer("aaa");

document.write(a.getDistance()); // 0
哦,按照惯例,构造函数名称以大写字母开头

function subSection(pattern){
    this.total = 0;
    this.pattern = pattern;
    this.distance=100;
}

function enhancer(pattern){
    this.__proto__=new subSection(pattern);
}

function silencer(pattern){
    this.__proto__=new subSection(pattern);
}

var a = new enhancer("aaa");
document.write(a.distance)​;
但正如
RobG
所说,这只是Mozilla的专有财产

更新:

function subSection(pattern){
    this.total = 0;
    this.pattern = pattern;
    this.distance=100;
}

function enhancer(pattern){
    function F(){};
    F.prototype = new subSection(pattern); // inherited subSection
    return new F();    
}

function silencer(pattern){
    function F(){};
    F.prototype = new subSection(pattern); // inherited subSection
    return new F();
}

var a = new enhancer("aaa");
document.write(a.distance)​;


有用链接:和。

您应该为对象使用原型继承。我会将您的增强器对象定义为:

function subSection(pattern){
    this.total = 0;
    this.pattern = pattern;
    this.distance=0;
}

function enhancer(pattern){
    __proto__:subSection;
    this.pattern = pattern;
}

function silencer(pattern){
    __proto__:subSection;
    this.pattern = pattern;
}

var a = new enhancer("aaa");
document.write(a.distance)
    //create Enhancer object
function Enhancer(pattern){
    this.subSection(pattern);    
}

//extend Enhancer with object methods
Enhancer.prototype = {

   subSection: function(pattern){
         this.pattern = pattern;
         this.total = 0;        
         this.distance=0;
  }

};
下面是我在这段代码中要说的:

  • 我用一个函数定义增强器对象。请注意,我将“Enhancer”大写,表示此数据结构的“object”
  • 我获取传递给对象的“pattern”值,并使用它调用Enhancer.subSection();我可以调用.subSection()作为增强器对象的方法,因为我使用.prototype将其定义为方法
    这里是这种方法的一个工作

    一般来说,应该在
    原型
    上而不是在构造函数中定义属性,如
    总计
    距离
    ,它们对于
    子部分
    对象的每个实例都要初始化为完全相同的值

    enhancer.prototype.constructor = enhancer;
    silencer.prototype.constructor = silencer;
    
    一个对象的
    原型
    基本上是一个“模板”,该对象的每个实例都基于该模板。每个实例都有在
    原型上定义的每个属性和方法

    因此,这三个“类”(JavaScript没有Java等经典继承语言中定义的类,但有时习惯于这些语言的人更容易使用这些术语)应该声明如下:

    function subSection(pattern) {
        this.pattern = pattern;
    }
    
    function enhancer(pattern) {
        this.pattern = pattern;
    }
    
    function silencer(pattern) {
        this.pattern = pattern;
    }
    
    total
    distance
    移出
    子部分
    构造函数,进入
    子部分
    原型:

    subSection.prototype.total = 0;
    subSection.prototype.distance = 0;
    
    下一步是在
    小节
    增强器
    消音器
    之间建立原型继承,使用no-op函数作为它们之间的代理:

    function fn() {}
    fn.prototype = subSection.prototype;
    
    enhancer.prototype = new fn();
    silencer.prototype = new fn();
    
    最后,将
    增强器
    消音器
    原型的
    构造函数
    属性设置为正确的对象,以便实例的
    构造函数
    属性引用正确的构造函数函数。如果我们不采取此步骤,则
    增强器
    消音器
    的任何实例都将错误地引用
    小节
    构造函数

    enhancer.prototype.constructor = enhancer;
    silencer.prototype.constructor = silencer;
    
    现在我们可以实例化
    增强器
    消音器
    对象,得到的实例将具有
    总计
    距离
    属性以及引用相应对象的
    构造函数
    属性

    var a, b;
    a = new enhancer('aaaa');
    b = new silencer('bbbb');
    console.log(a.total + ', ' + a.distance); // 0, 0
    console.log(b.total + ', ' + b.distance); // 0, 0
    console.log(a.constructor); // (string representation of enhancer constructor)
    
    我们在继承过程中使用
    fn
    函数作为代理的原因是,一个对象应该能够从另一个不一定具有相同构造函数参数集的对象继承

    假设我们有以下两个构造函数:

    function Person(name, age, hometown) {
        this.name = name;
        this.age = age;
        this.hometown = hometown;
    }
    
    function Employee(name, company, title) {
        this.name = name;
        this.company = company;
        this.title = title;
    }
    
    Employee
    应该能够从
    Person
    继承,即使它们不共享同一组构造函数参数。如果我们简单地将
    Employee.prototype
    设置为等于
    Person
    的一个新实例,那么
    Employee
    原型将具有三个未定义的属性
    name
    age
    homely

    Employee.prototype = new Person; // name, age and hometown are undefined
    var e = new Employee('John Smith', 'New York Times', 'editor'); // e's prototype has undefined properties name, age and hometown
    
    通过使用no-op函数
    fn
    (我们几乎可以随意命名),我们最终为每个实例创建了一个干净的原型,因为
    fn
    作为构造函数不需要任何参数


    这是不必要的,但它是一种设置原型继承的更简洁的方法:没有太多理由用未定义的属性来混乱原型。

    在哪里调用Enhancer.prototype=new SubSection();从…起我应该把它放在我的代码中的什么地方,这样其他程序员就可以得到它?@Tom-假设所有代码都在全局名称空间中,那么在哪里调用这行代码并不重要。在JavaScript中,函数声明被提升到其作用域的顶部,因此无论在哪里声明子节和增强器函数,JavaScript都会将它们视为在脚本的最开始就声明了。Enhancer.prototype=new SubSection()可以在函数声明之前、之后或之间调用。函数声明是在执行任何代码之前处理的,您可以将它们放在同一脚本块的任何位置(或多或少),将它们按顺序排列是一个好习惯,这样函数就直接声明在原型修改的地方(根据上面的代码)。我发现它可读性更高,更容易理解。正是我所寻找的WebKit浏览器也支持proto属性,Opera也是如此。我猜问题发生在Internet Explorer中。:-)谢谢你,克里斯!但这意味着在创建10个继承相同内容的类时会有大量代码重复,实际上JavaScript中的所有内容都是对象。数组、字符串、日期、数字和函数都是对象。“Enhancer”的大写是一种惯例,通常用于表示特定函数将充当返回该对象实例的构造函数。@Tom-如果为Enhancer.prototype.subSection分配了subSection函数,则此技术不需要任何代码重复。是否有particu