在JavaScript中使用'prototype'与'this'? [英] Use of 'prototype' vs. 'this' in JavaScript?

查看:137
本文介绍了在JavaScript中使用'prototype'与'this'?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有什么区别

var A = function () {
    this.x = function () {
        //do something
    };
};

var A = function () { };
A.prototype.x = function () {
    //do something
};


推荐答案

这些例子的结果截然不同。

The examples have very different outcomes.

在查看差异之前,应注意以下几点:

Before looking at the differences, the following should be noted:


  • 构造函数的 prototype 提供了一种通过实例的私有 [[Prototype]] 属性在实例之间共享方法和值的方法。

  • 函数的 this 由函数的调用方式或 bind (此处未讨论)设置。如果在对象上调用函数(例如 myObj.method()),则方法中的 this 引用该对象。如果未通过调用或使用 bind 设置,则默认为全局对象(浏览器中的窗口)或严格模式,仍未定义。

  • JavaScript是一种面向对象的语言,即一切都是对象,包括函数。

  • A constructor's prototype provides a way to share methods and values among instances via the instance's private [[Prototype]] property.
  • A function's this is set by how the function is called or by the use of bind (not discussed here). Where a function is called on an object (e.g. myObj.method()) then this within the method references the object. Where this is not set by the call or by the use of bind, it defaults to the global object (window in a browser) or in strict mode, remains undefined.
  • JavaScript is an object-oriented language, i.e. everything is an Object, including functions.

所以这里是有问题的片段:

So here are the snippets in question:

var A = function () {
    this.x = function () {
        //do something
    };
};

在这种情况下,分配变量 A 一个值,它是对函数的引用。当使用 A()调用该函数时,函数的 this 不会被调用设置,因此它默认为全局对象和表达式 this.x 有效 window.x 。结果是对右侧的函数表达式的引用被赋给 window.x

In this case, variable A is assigned a value that is a reference to a function. When that function is called using A(), the function's this isn't set by the call so it defaults to the global object and the expression this.x is effective window.x. The result is that a reference to the function expression on the right-hand side is assigned to window.x.

在以下情况下:

var A = function () { };
A.prototype.x = function () {
    //do something
};

发生了一些非常不同的事情。在第一行中,变量 A 被赋予对函数的引用。在JavaScript中,默认情况下所有函数对象都具有 prototype 属性,因此没有单独的代码来创建 A.prototype 对象。

something very different occurs. In the first line, variable A is assigned a reference to a function. In JavaScript, all functions objects have a prototype property by default so there is no separate code to create an A.prototype object.

在第二行中, A.prototype.x 被赋予对函数的引用。如果它不存在,这将创建 x 属性,如果不存在,则分配新值。因此,与表达式中涉及对象的 x 属性的第一个示例的区别。

In the second line, A.prototype.x is assigned a reference to a function. This will create an x property if it doesn't exist, or assign a new value if it does. So the difference with the first example in which object's x property is involved in the expression.

下面是另一个示例。它与第一个类似(也许你想问的是):

Another example is below. It's similar to the first one (and maybe what you meant to ask about):

var A = new function () {
    this.x = function () {
        //do something
    };
};

在此示例中, new 运算符具有在函数表达式之前添加,以便将该函数作为构造函数调用。当使用 new 调用时,函数的 this 被设置为引用一个新的Object,其私有 [[Prototype]] 属性设置为引用构造函数的public prototype 。因此,在赋值语句中,将在此新对象上创建 x 属性。当作为构造函数调用时,函数默认返回其 this 对象,因此不需要单独的返回此; 语句。

In this example, the new operator has been added before the function expression so that the function is called as a constructor. When called with new, the function's this is set to reference a new Object whose private [[Prototype]] property is set to reference the constructor's public prototype. So in the assignment statement, the x property will be created on this new object. When called as a constructor, a function returns its this object by default, so there is no need for a separate return this; statement.

要检查 A 是否有 x 属性:

console.log(A.x) // function () {
                 //   //do something
                 // };

这是 new 的罕见用法,因为唯一的方法是引用构造函数是通过 A.constructor 。这样做会更常见:

This is an uncommon use of new since the only way to reference the constructor is via A.constructor. It would be much more common to do:

var A = function () {
    this.x = function () {
        //do something
    };
};
var a = new A();

实现类似结果的另一种方法是使用立即调用的函数表达式:

Another way of achieving a similar result is to use an immediately invoked function expression:

var A = (function () {
    this.x = function () {
        //do something
    };
}());

在这种情况下, A 分配了回报在右侧调用函数的值。在这里,由于未在调用中设置此,它将引用全局对象并且 this.x 有效 window.x 。由于该函数不返回任何内容, A 的值为 undefined

In this case, A assigned the return value of calling the function on the right-hand side. Here again, since this is not set in the call, it will reference the global object and this.x is effective window.x. Since the function doesn't return anything, A will have a value of undefined.

如果您将Javascript对象序列化和反序列化为JSON,则这两种方法之间的差异也会显现出来。在序列化对象时,在对象的原型上定义的方法不是序列化的,例如,当您想要仅序列化对象的数据部分时,这可能很方便,但不是它的方法:

These differences between the two approaches also manifest if you're serializing and de-serializing your Javascript objects to/from JSON. Methods defined on an object's prototype are not serialized when you serialize the object, which can be convenient when for example you want to serialize just the data portions of an object, but not it's methods:

var A = function () { 
    this.objectsOwnProperties = "are serialized";
};
A.prototype.prototypeProperties = "are NOT serialized";
var instance = new A();
console.log(instance.prototypeProperties); // "are NOT serialized"
console.log(JSON.stringify(instance)); 
// {"objectsOwnProperties":"are serialized"} 

相关问题

  • What does it mean that JavaScript is a prototypal language?
  • What is the scope of a function in JavaScript?
  • How does the "this" keyword work?

旁注:可能没有任何重要的记忆两种方法之间的节省,但是使用原型共享方法和属性可能会比每个拥有自己副本的实例使用更少的内存。

Sidenote: There may not be any significant memory savings between the two approaches, however using the prototype to share methods and properties will likely use less memory than each instance having its own copy.

JavaScript不低等级语言。将原型设计或其他继承模式视为显式更改内存分配方式的方法可能不是很有价值。

JavaScript isn't a low-level language. It may not be very valuable to think of prototyping or other inheritance patterns as a way to explicitly change the way memory is allocated.

这篇关于在JavaScript中使用'prototype'与'this'?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆