Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/424.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
javascript类从函数类继承_Javascript_Inheritance_Prototypal Inheritance_Function Object - Fatal编程技术网

javascript类从函数类继承

javascript类从函数类继承,javascript,inheritance,prototypal-inheritance,function-object,Javascript,Inheritance,Prototypal Inheritance,Function Object,我喜欢在javascript中,我可以创建一个函数,然后向该函数添加更多的方法和属性 myInstance = function() {return 5} myInstance.attr = 10 我想创建一个类来生成这些对象。我假设我必须从函数基类继承 换言之,我想: var myInstance = new myFunctionClass() var x = myInstance() // x == 5 但是我不知道如何创建myFunctionClass。我尝试了以下方法,但无效: va

我喜欢在javascript中,我可以创建一个函数,然后向该函数添加更多的方法和属性

myInstance = function() {return 5}
myInstance.attr = 10
我想创建一个类来生成这些对象。我假设我必须从函数基类继承

换言之,我想:

var myInstance = new myFunctionClass()
var x = myInstance()
// x == 5
但是我不知道如何创建myFunctionClass。我尝试了以下方法,但无效:

var myFunctionClass = function() {Function.call(this, "return 5")}
myFunctionClass.prototype = new Function()
myInstance = new myFunctionClass()
myInstance()
// I would hope this would return 5, but instead I get
// TypeError: Property 'myInstance' of object #<Object> is not a function
var myFunctionClass=function(){function.call(这是“返回5”)}
myFunctionClass.prototype=新函数()
myInstance=新的myFunctionClass()
myInstance()
//我希望这将返回5,但我得到了
//TypeError:对象#的属性“myInstance”不是函数
我还尝试了这里发现的更复杂(更合适?)的继承方法:,但运气不好。我还尝试使用node.js中的util.inherits(myFunctionClass,Function)。还是不走运


我已经用尽了谷歌,因此我觉得我一定错过了一些基本的或明显的东西。非常感谢您的帮助。

您试图从
函数继承。这是一个正确的做法。我建议你改为做以下事情

您希望创建一个原型对象,该对象构成“类”的基础。它具有您的通用方法/属性。它还有一个在对象构造时调用的构造函数和一个在调用函数时调用的调用方法

var functionFactory = function (proto) {
  return function () {
    var f = function () {
      return f.call.apply(f, arguments);      
    };
    Object.keys(proto).forEach(function (key) {
      f[key] = proto[key];
    });
    f.constructor.apply(f, arguments);
    return f;
  }
}
函数工厂获取原型对象并为其返回工厂。调用时返回的函数将为您提供一个从原型对象“继承”的新函数对象

var protoFactory = functionFactory(proto);
var instance = protoFactory();
在这里创建工厂,然后创建实例

然而,这不是典型的OO。我们只是简单地将原型的属性复制到一个新对象中。因此,对原型的更改不会反映回原始对象

如果您想要真正的原型OO,那么您需要使用hack

var f = function () {
  // your logic here
};
f.__proto__ = Proto;

注意我们是如何使用非标准的弃用
。\uuuu proto\uuuu
的,我们在运行时对
[[Prototype]]
的值进行了变异,这被认为是有害的。

JS不允许构造函数返回函数,即使函数是对象。所以你不能有一个原型的实例,它本身是可执行的。(我说的对吗?如果不对,请更正,这是一个有趣的问题)

虽然您可以执行工厂功能:

var makeCoolFunc = function() {
  var f = function() { return 5 };
  f.a = 123;
  f.b = 'hell yes!'
  return f;
};

var func = makeCoolFunc();
var x = func();

您可以扩展
函数
,并将所需的函数体作为字符串传递给超级构造函数。可以使用
参数访问函数的上下文。被调用方

可观察属性类的示例:

    export default class Attribute extends Function  {

    constructor(defaultValue){
        super("value", "return arguments.callee.apply(arguments);");
        this.value = defaultValue;
        this.defaultValue = defaultValue;
        this.changeListeners = [];
    }

    apply([value]){
        if(value!==undefined){
           if(value!==this.value){
               var oldValue = this.value;
               this.value=value;
               this.changeListeners.every((changeListener)=>changeListener(oldValue, value));
           }
        }
        return this.value;
    }

    clear(){
        this.value=undefined;
    }

    reset(){
        this.value=this.defaultValue;
    }

    addChangeListener(listener){
        this.changeListeners.push(listener);
    }

    removeChangeListener(listener){
        this.changeListeners.remove(listener);
    }

    clearChangeListeners(){
        this.changeListeners = [];
    }
}
用法示例:

import Attribute from './attribute.js';

var name= new Attribute();
name('foo'); //set value of name to 'foo'

name.addChangeListener((oldValue, newValue)=>{
    alert('value changed from ' +oldValue+ ' to ' +newValue);
});
alert(name()); //show value of name: 'foo'

name('baa'); //set value of name to new value 'baa' and trigger change listener

在ECMAScript第三版中,无法执行此操作(使用
[[prototype]]]
)。我不知道是否有一个棘手的方法,在第五版,允许这一点,或没有。“常规”方法——例如jQuery中使用的方法——从“原型”复制单个属性,而不使用原型继承。“JS不允许构造函数返回函数”——我认为这是不对的。您可以从构造函数返回函数对象。当然,它可能会返回它,但是如果您返回的不是
this
,那么返回值就不会有构造函数原型,对吗?所以没什么意义。示例:可以从构造函数返回函数。但是,您不能返回具有内部
[[Call]]
属性的原型的实例化。这几乎就是我正在寻找的解决方案。但是,如何从方法中访问实例的属性<代码>此
不起作用;我想把
that=this
放在构造函数中,然后引用
that.attribute
就行了。但是
that
总是指向最近创建的实例,而不是指向我从中调用该方法的实例。@dgreisen
this
在方法内部和构造函数内部
this
工作,在
调用
方法
this
工作。但是我不会为你调用构造函数,你必须自己去做。我已经编辑了代码,所以构造函数called@Raynos,谢谢你的回复。我的代码调用构造函数,所以我认为这不是问题所在。问题说明:在实例中,添加到构造函数:
this.d=d;修改对
console.log的调用(“调用”,this.d);在末尾添加:
instance.call()。instance.call()正确记录“调用数据”。instance()记录“调用未定义”。如果我理解正确,
这个
指的是函数的所有者。instance.call()的所有者是instance->
引用实例。但是instance()本身的所有者是window->
这个
指向window,而不是instance。是否有一个关键字可以从instance()中指向instance,这样我就可以从instance()访问instance.d?这正是我所需要的。非常感谢。
import Attribute from './attribute.js';

var name= new Attribute();
name('foo'); //set value of name to 'foo'

name.addChangeListener((oldValue, newValue)=>{
    alert('value changed from ' +oldValue+ ' to ' +newValue);
});
alert(name()); //show value of name: 'foo'

name('baa'); //set value of name to new value 'baa' and trigger change listener