在javascript中创建另一个对象的实例

时间:2012-08-30 22:51:39

标签: prototypejs prototype-programming javascript

我想知道这句话是否正确?

你可以这样做:

var a = new A();

当且仅当Ainstanceof Function时。

只需创建一个函数实例,您就知道函数是一个对象。为什么我们不能创建其他用户定义对象的实例?像这样:

var b={};
var c = new b();  //error

编辑:如何更改b以便我可以创建一个实例?

4 个答案:

答案 0 :(得分:4)

你实际上可以使用Object.create()在ECMAscript的原型性质上加糖。像

var b = { };
var c = Object.create( b );

现在,c将在其原型链上拥有b。 ECMAscript或更准确地说,原型继承与“经典继承”的工作方式不完全相同。通过在调用函数时调用new,您实际上也会收到一个新创建的对象。您可以通过名为构造函数this值修改和访问该对象。

但是,到目前为止,你没有继承任何东西。在创建构造函数之前,您需要为构造函数创建并填充.prototype - 对象。这种模式让很多人感到恼火,因此ES5使用Object.create()作为一种更方便的方式直接从其他对象继承。

答案 1 :(得分:3)

简短回答:new运算符要求其操作数具有通用对象所没有的特殊内部方法[[Construct]]

答案很长:

11.2.2 The new Operator
The production NewExpression : new NewExpression is evaluated as follows:
    1. Evaluate NewExpression.
    2. Call GetValue(Result(1)).
    3. If Type(Result(2)) is not Object, throw a TypeError exception.
    4. If Result(2) does not implement the internal [[Construct]] method, throw a TypeError exception.
    5. Call the [[Construct]] method on Result(2), providing no arguments (that is, an empty list of arguments).
    6. Return Result(5).

    The production MemberExpression : new MemberExpression Arguments is evaluated as follows:

    1. Evaluate MemberExpression.
    2. Call GetValue(Result(1)).
    3. Evaluate Arguments, producing an internal list of argument values (11.2.4).
    4. If Type(Result(2)) is not Object, throw a TypeError exception.
    5. If Result(2) does not implement the internal [[Construct]] method, throw a TypeError exception.
    6. Call the [[Construct]] method on Result(2), providing the list Result(3) as the argument values.
    7. Return Result(6).

答案 2 :(得分:3)

  

只需创建一个函数实例,您就知道函数是一个对象。为什么我们不能创建其他用户定义对象的实例?

说“你可以创建一个功能实例”是不正确的。 new关键字有点误导 - 它使JavaScript看起来像使用类实现面向对象,而事实上它并没有。

您实际使用new A()执行的操作是使用构造函数A创建对象。 new关键字告诉JavaScript解释器从A返回一个对象 - 特别是this内部称为A的对象。

  

编辑:如何更改b以便我可以创建一个实例?

在您的示例中,b是一个对象(var b={};)。如果将b更改为构造函数,则可以使用它创建对象。 (按照惯例,JavaScript中的构造函数以大写字母开头。)

所以:

function B () {
}

var c = new B();

您可以将内容添加到prototype的{​​{1}}对象中,也可以B访问它们(以及使用c创建的任何其他对象) :

B

答案 3 :(得分:1)

您也可以

var b = new a.constructor();