Javascript 对象文本作为原型

Javascript 对象文本作为原型,javascript,Javascript,这个问题更多的是关于支持和向后兼容性。我已经测试了以下代码 function newFunc() {} newFunc.prototype = { literal : { init : function() { console.log(this); this.test(); }, test : function() { console.log('test');

这个问题更多的是关于支持和向后兼容性。我已经测试了以下代码

function newFunc() {}

newFunc.prototype = {

    literal : {
        init : function() {
            console.log(this);
            this.test();
        },
        test : function() {
            console.log('test');
        }
    }
}

var inst = new newFunc();

inst.literal.init();

这是可行的,尽管我在任何其他代码中都没有看到对象文本作为原型。这有什么原因吗?对我来说,这似乎是一种合乎逻辑的编码方式,但如果它有严重的缺陷,我不想继续使用它。

如果我理解正确,他们会说你可以用javascript(ECMA脚本)实现这一点

但我知道的是,如果你想实例化你的对象,旧浏览器会有一个问题,那就是你不能用Object.create()函数来实例化对象

所以你通常应该这样做

var foo = function(){};
foo.prototype = {func:function(){}}
var bar = new foo();

像您这样做:)

您所做的是用几个属性设置原型。这是完全可以接受的,因为函数的行为与JavaScript中的对象非常相似。JavaScript所做的就是将对这个原型属性的引用向下传递给继承的对象,这样它们就不会有一个可以访问的函数,而是一个对象

您可以在MDN文档中看到这一点:

var Person = {
    canTalk : true,
    greet : function() {
        if (this.canTalk) {
            console.log("Hi, I'm "+this.name)
        }
    }
}
Customer.prototype = Person;

是的,对原型使用文本是正确的。例如,Mozilla在原型的


一些解释:原型的值是一个对象。对象是如何创建的并不重要,只需使用
{}
即可。它通常使用类似于
MyClass1.prototype=newmyclass2()
的东西初始化,但是
new
只是创建一个新对象。它还设置
prototype
属性并执行构造函数(
MyClass2
),但在新对象上,它不会以任何方式影响
MyClass1
(请参见说明)

使用嵌套文字并没有什么区别。在这个问题中,原型被设置为
{literal:{…}
。调用
inst.literal.init()时实际发生的情况是:

  • 运行时查看
    inst
    ,并检查对象是否为属性
    literal
    指定了值
  • inst
    dos没有这样的属性,因此运行时继续使用其
    prototype
    属性
  • inst.prototype
    引用初始化它的文本对象。此对象已为属性
    文字
    指定了一个值
  • inst.literal
    因此计算为嵌套的literal
    inst.prototype.literal
  • 文字对象的属性
    init
  • 调用
    init()
    函数

  • 这是JavaScript(ECMA脚本)的原则之一,因此不存在兼容性问题。

    使用对象文字为函数创建原型是完全正常的,但通常仅作为
    原型
    对象的实际值

    不寻常的是,您所做的是在原型中包含嵌套对象

    实际上,您只向原型添加了一个对象,即名为
    literal
    的对象。所有方法都是该对象的属性。它在技术上是有效的语法,但我以前从未见过使用它。正如@squint在评论中指出的,它似乎也打破了
    this
    变量的工作方式,因为它将
    this
    绑定到函数调用中使用的“next left”属性:

    var inst = new newFunc();
    inst.literal.init();
    > Object { init: function, test: function }
    

    i、 e.
    已设置为指向
    .literal
    对象,而不是指向已创建的实际实例。

    好吧,任何人都可以随意交换
    literal.init
    ,并且更改将反映在所创建的每个实例上。如果没有中间的
    literal
    阶段,这是不可能的。@jon我理解,我想我真的想知道,如果没有其他词,“ok”:-)我会说,就像JavaScript中的几乎所有东西一样,
    prototype
    只是一个对象,因此可以像任何其他对象一样创建或重新分配。我已经见过这种模式很多次了,但我也很好奇这是否有一些缺点。我会说“不”…但这是个好问题。@斜视,嗯,好吧,让我检查一下。。。是的,是的,你是对的。“太可怕了!”谢谢你的评论,这可能就是我不走这条路的原因。没有双关语的意思。。。谢谢对不起,这怎么会是对文字的误用?@Mathletics它实际上是一个JavaScript对象文字。你在对象文字和JavaScript对象文字之间挑拨离间吗?而且,它仍然不是JSON,所以你的链接有误导性。@AlexW:忘记“JSON”中的“JS”。这只是对在形成JSON语法时部分使用的文字语法的一种认可。JSON是一种数据传输格式。在JavaScript程序中将对象文字语法称为JSON是没有意义的,因为您不能直接将语法结果用于数据传输@斜视击败了我,给了我一个完美的回答,但是欢迎你阅读。你注意到OP的代码中实际上有一个嵌套的
    文字
    ?我知道原型是什么,以及它是如何工作的。我的问题是,正如Alnitak所提到的关于将对象嵌套为原型的更多内容一样。@Mifeet它确实起到了作用-根据问题上的注释,嵌套属性会破坏
    。不幸的是,使用嵌套对象时,整个上下文都会更改。除非你在给定的上下文中明确地调用它,否则我认为它不会feasible@Alnitak好吧,我们总是需要小心这件事。很明显,你的答案对David来说是正确的。实际上,这只是一个例子,我希望有多个嵌套对象作为原型,或者是嵌套对象和函数原型的混合体。谢谢你的回答,这正是我想要的澄清。至于编辑,是的,这正是我想要的
    var inst = new newFunc();
    inst.literal.init();
    > Object { init: function, test: function }