简体   繁体   English

javascript 原型

[英]javascript prototype

I AM trying to understand js prototype property: my sample code我正在尝试理解 js 原型属性:我的示例代码

function Container(param) {
    this.member = param;
}

var newc = new Container('abc');


Container.prototype.stamp = function (string) {
    return this.member + string;
}

document.write(newc.stamp('def'));

function Box() {
    this.color = "red";
    this.member = "why";
}

Container.prototype = new Box();
Box.prototype.test = "whatever";
var b = new Box();

document.write(newc.test);

here the last line is undefined - even though Container's prototype is a Box and Box's prototype has a property test, why is the newc which refers to test in Box doesnt work?这里最后一行是未定义的——尽管 Container 的原型是 Box 并且 Box 的原型具有属性测试,但为什么在 Box 中引用 test 的 newc 不起作用? can any one please explain how the 'Prototype' works in my above context.任何人都可以解释一下“原型”在我上面的上下文中是如何工作的。

Thanks...谢谢...

You are setting Container prototype to Box() after the newc instance was already created.在创建newc实例之后,您将Container原型设置为Box()

Reorder the statements as follows:将语句重新排序如下:

function Container(param) {
    this.member = param;
}

function Box() {
    this.color = "red";
    this.member = "why";
}

Container.prototype = new Box();
Box.prototype.test = "whatever";
Container.prototype.stamp = function (string) {
    return this.member + string;
}

//Here the containers prototype setup is complete.
var newc = new Container('abc');

document.write(newc.stamp('def'));

document.write(newc.test);

If sounds like you want to know WHY it is behaving the way it is, and not just "fix" the code.如果听起来您想知道为什么它的行为方式是这样,而不仅仅是“修复”代码。 So here's what's going on.所以这就是发生的事情。

As you saw, if you change the prototype of "Container", you will actually change the properties for new objects AND objects already instantiated.如您所见,如果您更改“容器”的原型,您实际上将更改新对象和已实例化对象的属性。 So:所以:

function Container(param) {
    this.member = param;
}

var newc = new Container('abc');

// setting a new property of the prototype, after newc instantiated.
Container.prototype.stamp = function (string) {
    return this.member + string;
}

// This already-instantiated object can access the stamp function
document.write(newc.stamp('123')); // output: abc123

So there's no problem with the above, as long as you don't call the new method before it's defined.所以上面的没有问题,只要在新方法定义之前不调用它就可以了。 Now the next point.现在下一点。 Add this to the above:将其添加到上面:

// Our Box object
function Box() {
    this.color = "red";
    this.member = "why";
}

Container.prototype = new Box();
var newd = new Container('fgh');
document.write(newd.stamp('456')); // output: ERROR

Error, But that makes sense?错误,但这有意义吗? right, You totally wiped out the "Container" prototype and replaced it with the one from "Box".对,你完全消灭了“Container”原型,并用“Box”中的原型替换了它。 which has no "stamp" function.它没有“邮票”功能。

I am going to assume you want "Box" to inherit from "Container".我将假设您希望“Box”从“Container”继承。 That would be logical from the naming convention.从命名约定来看,这是合乎逻辑的。 If you want to do that, replace the previous section with this:如果您想这样做,请将上一节替换为:

// Our Box object
function Box() {
    this.color = "red";
    this.member = "why";
}

// This inherits from Container. Note that we can
//   do this before or after we declare "Box"
Box.prototype = new Container();

Box.prototype.test = "Whatever";
var b = new Box("jkl"); // note: "jkl" is ignored because "Box" sets "member" to "why"

document.write(b.test); // output: Whatever
document.write("<br>");
document.write(b.stamp("345")); // output: why345

So now we have a "Box" that can call its own methods and parameters, and also call them from its parent "Container".所以现在我们有了一个“盒子”,它可以调用它自己的方法和参数,也可以从它的父“容器”中调用它们。

So the big picture is that an object will look at its own prototype for a method or something, and if it doesn't find it there it will look in the prototype of the thing it inherited from, and so on.所以总体情况是,object 将查看它自己的原型以寻找方法或其他东西,如果在那里找不到它,它将查看它继承的东西的原型,依此类推。 The other big point is that setting something in the prototype makes it immediately available in all future AND current instances of that object.另一个重要的一点是,在原型中设置一些内容可以使其在 object 的所有未来和当前实例中立即可用。

An object does not contain a reference to its constructor which it uses to get at the prototype. object 不包含对其用于获取原型的构造函数的引用。 If it did, then the code would work as you expected.如果是这样,那么代码将按您的预期工作。

Instead, an object contains a reference to its prototype that is set when it is created.相反,object 包含对其原型的引用,该原型在创建时设置。

From the language spec section 4.2.1 :从语言规范第4.2.1节:

Every object created by a constructor has an implicit reference (called the object's prototype) to the value of its constructor's “prototype” property.每个由构造函数创建的 object 都有一个对其构造函数“原型”属性值的隐式引用(称为对象的原型)。 Furthermore, a prototype may have a non-null implicit reference to its prototype, and so on;此外,原型可能具有对其原型的非空隐式引用,依此类推; this is called the prototype chain.这称为原型链。 When a reference is made to a property in an object, that reference is to the property of that name in the first object in the prototype chain that contains a property of that name.当引用 object 中的属性时,该引用是指原型链中包含该名称的属性的第一个 object 中的该名称的属性。 In other words, first the object mentioned directly is examined for such a property;换句话说,首先检查直接提到的 object 的这种属性; if that object contains the named property, that is the property to which the reference refers;如果该 object 包含命名属性,即引用所指的属性; if that object does not contain the named property, the prototype for that object is examined next;如果该 object 不包含指定属性,则接下来检查该 object 的原型; and so on.等等。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM