Javascript对象原型混乱(使用require.js和three.js)

时间:2014-04-12 22:01:46

标签: javascript oop three.js requirejs prototype

基本上我感到困惑的是与我对Objects / prototypes,require.js或three.js的理解有关。这是一个例子:

TLDR:

“wee”是“Wee”的一个实例,它是THREE的包装/猴子补丁......

因此,“wee”不应具有THREE的属性和方法吗?

(传递属性和诸如此类:a = b = c; a = c。)

define (['three'], function () {
    function WEE(){
      THREE;
      return THREE;
    }
    var test = new WEE;
    console.log("test");
    console.log(test);
    function Wee(){
      WEE.call(this);
      this.prototype = new WEE();
      this.width = window.innerWidth;
      this.height = window.innerHeight;
      this.aspectRatio = window.innerWidth / window.innerHeight;
    }
    var wee = new Wee();
    console.log("wee");
    console.log(wee);
});

这是我开始感到困惑的地方......

chrome中的'test'日志显示:

test
Object {REVISION: "66", CullFaceNone: 0, CullFaceBack: 1, CullFaceFront: 2, CullFaceFrontBack: 3…}

这很好。我的目标是创建一个three.js的猴子补丁。

然而,当我在Chrome中记录时,它会显示:

 wee
 Wee {prototype: Object, width: 1920, height: 1102, aspectRatio: 1.7422867513611615}

扩展原型细节的东西我可以看到原型是Wee,这是三个 - 这也很好......但令我困惑的是,我的代码后面会这样做:

var renderer = new wee.WebGLRenderer();

并返回“undefined”。

我也试过

var renderer = wee.WebGLRenderer;
var renderer = wee.WebGLRenderer();

所有失败的“Uncaught TypeError:undefined不是函数。

问题:

  1. 发生了什么事?
  2. 我错过了什么?
  3. 为什么一开始就完全可以使用THREE,因为我的定义函数需要它,但不会将它分配给任何东西?
  4. 我问的是正确的问题吗?有什么不同的方式来表达它,以便下次我可以谷歌吗?

1 个答案:

答案 0 :(得分:2)

这一行:

this.prototype = new WEE();

在名为prototype的对象上创建属性。它没有设置对象的底层原型(它不称为prototype;它现在在标准中是匿名的,有些实现称之为__proto__)。您也可以将该属性称为robert

以两种方式之一设置对象的原型(现在):

  1. 如果您通过new FunctionName创建对象,则其基础原型是根据您使用FunctionName.prototype运算符时引用的new设置的。

  2. 如果您通过Object.create创建对象,那么无论您传递给Object.create来分配原型。

  3. 所以:

    function Foo() {
    }
    Foo.prototype = {
        bar: 42
    };
    var f = new Foo();
    console.log(f.bar); // 42
    

    var f = Object.create({
        bar: 42
    });
    console.log(f.bar); // 42
    

    但值得注意的是:

    function Foo() {
        this.prototype = {
            bar: 42
        };
    }
    var f = new Foo();
    console.log(f.bar);           // undefined
    console.log(f.prototype.bar); // 42
    

    请注意,在prototype创建的实例上创建名为new Foo的属性对设置该实例的原型没有任何作用。

    这是JavaScript的一个很大的混乱:函数的prototype属性不是函数的原型,如果你通过函数创建对象,它是new将分配给对象的原型new FunctionName。对象没有任何代表其原型的命名属性(目前为交叉实现)。

    在ES6(规范的下一个版本)中,__proto__属性访问器非常非常可能被定义为允许我们直接访问和设置对象的原型。 (这是在规范草案中,这意味着它已经清除了多个级别的审核;我现在看不到它被删除了。)目前SpiderMonkey(Firefox的JavaScript引擎)支持这一点,而其他几个也可以支持,但它是不标准。