首页 \ 问答 \ 为什么我要设置Manager.prototype?(Why do I set Manager.prototype?)

为什么我要设置Manager.prototype?(Why do I set Manager.prototype?)

在这个参考文献中 ,下面是Javascript代码,

function Manager() {
  Employee.call(this);
  this.reports = [];
}
Manager.prototype = Object.create(Employee.prototype);

为相应的Java代码。

public class Manager extends Employee {
   public Employee[] reports = new Employee[0];
}

Manager.prototype在上面的代码中设置。 Employee.prototype未设置为参考中所示。

function Employee() {
  this.name = "";
  this.dept = "general";
}

如果通过显式调用Employee.call(this);Employee属性添加到Manager Employee.call(this); ,那么为什么我们需要设置Manager.prototypeEmployee.prototype包含什么?

如果我没有在上面的代码中设置Manager.prototype ,你能否澄清一下问题?


In this reference, below is the Javascript code,

function Manager() {
  Employee.call(this);
  this.reports = [];
}
Manager.prototype = Object.create(Employee.prototype);

for corresponding Java code.

public class Manager extends Employee {
   public Employee[] reports = new Employee[0];
}

Manager.prototype is set in the above code. Employee.prototype is not set as shown in the reference.

function Employee() {
  this.name = "";
  this.dept = "general";
}

If Employee properties were added to Manager by explicitly calling Employee.call(this);, then why do we need to set Manager.prototype? What does Employee.prototype contains?

Can you please clarify the problem, if I do not set Manager.prototype in the above code?


原文:https://stackoverflow.com/questions/32241407
更新时间:2023-01-27 20:01

最满意答案

我看到有人在JavaScript中使用“Java”。 :)

关于JavaScript你应该了解的几件事:

  1. 在JavaScript中,数组不像其他语言那样工作。 它们更像是字典,然后用C或Java称为数组; 它们没有更高的内存效率或更快; 没有预先分配; 在低级实现中没有任何缺陷等。 JavaScript数组只是一个方便(但有用!)的结构,用于保存命令命令数据。

  2. 可以使用new Array(length)表达式或简单的文字表达式[]创建new Array(length) 。 通常,您需要使用数组文字[]

  3. 使用new Array(length)并没有真正做任何有用的事情; 它设置了数组的初始length属性,但基本上就是这样。 所有元素都undefined 。 没有其他约束或边界检查。 你可以在通过调用var a = new Array(5)创建的数组上执行a[100] = 'whatever' ,并且解释器不会瞄准。

  4. JavaScript使用原型继承,这与C ++和Java等语言中使用的经典继承模型有很大不同。

考虑到这些要点,让我们检查以下代码块:

function SongDatabase() {
    this.songs = new Array();
    this.loadSongs = function () {
        // etc.
    };

    this.saveSongs = function () {
        // etc.
    };

    var _Constructor_ = function () {
        var mySong = new Song();
        this.songs = new Array(mySong);
    };
    _Constructor_();
}

这段代码可能没有按照您的想法进行。

  1. 通过初始化SongDatabase()函数内的SongDatabase方法,您可以为songDatabase每个实例创建新的方法函数。 当你处理几十个实例时,这可能不是什么大问题,但是如果你要处理数百个实例,那么所需的额外内存可能会成为一个问题。 你想在这里使用prototype模式(见下文)。
  2. 你的_Constructor_函数没有做任何事情。 var mySong = new Song()_Constructor_函数的本地创建一个新的mySong对象,并且不能在其外部访问 。 当_Constructor_调用返回时,它的mySong变量被垃圾收集(就像任何其他局部变量一样)。
  3. _Constructor_是一个私有函数,而不是一个方法 ; 我不完全确定在这种情况下会引用什么。 您最终可能会在全局对象上创建一个歌曲属性(但我想测试它是否确定)。
  4. 正如我之前提到的,当您使用new运算符调用Array()时,它会使用一个可选参数来设置数组的初始length 。 在这种情况下,解释器会尝试将mySong强制转换为数字( mySong 不会添加到数组中!); 当失败时,它将返回一个length = 0的新数组。

相反,你SongDatabase()好像这样编写SongDatabase()

function SongDatabase() {
    this.songs = [];
    // etc.
}

SongDatabase.prototype.loadSongs = function () {
    // load songs into `this.songs`
};

SongDatabase.prototype.saveSongs = function () {
    // save songs loaded into `this.songs`
};

原型模式可能看起来很奇怪,但它可能是处理用例的最佳方式。 您仍然可以直接访问那些songs数组(可能重要也可能不重要),通过将loadSongssaveSongs函数附加到SongDatabase的原型,您可以确保共享这些函数。


I see someone's taking the "Java" in JavaScript too literally. :)

A couple things you should know about JavaScript:

  1. In JavaScript, arrays don't work like they do in other languages. They're a lot more like dictionaries then what you would call an array in C or Java; they're not significantly more memory efficient, or faster; no preallocation is done; there's no offeset, etc, in the low-level implementation. JavaScript arrays are little more than a convenient (but useful!) structure for holding order-imperative data.

  2. Arrays can be created using the new Array(length) expression, or the simple literal expression, []. Generally, you'll want to use the array literal, [].

  3. Using new Array(length) doesn't really do anything useful; it sets the initial length property of the array, but that's basically it. All elements remain undefined. There are no additional constraints or bounds checking. You can do a[100] = 'whatever' on an array created by calling var a = new Array(5) and the interpreter won't bat an eye.

  4. JavaScript uses prototypal inheritance which is significantly different then the classical inheritance model used in languages like C++ and Java.

With these points in mind, lets examine the following code block:

function SongDatabase() {
    this.songs = new Array();
    this.loadSongs = function () {
        // etc.
    };

    this.saveSongs = function () {
        // etc.
    };

    var _Constructor_ = function () {
        var mySong = new Song();
        this.songs = new Array(mySong);
    };
    _Constructor_();
}

This block of code is probably not doing what you think it's doing.

  1. By initializing the SongDatabase methods inside the SongDatabase() function you're creating new method functions for every instance of songDatabase. This may not be a big deal when you're dealing with a couple of dozen of instances, but if you're dealing with hundreds, the extra memory required can become a problem. You'll want to use the prototype pattern here, instead (see below).
  2. Your _Constructor_ function isn't doing anything. var mySong = new Song() creates a new mySong object local to the _Constructor_ function and not accessible outside of it. When the _Constructor_ invocation returns, it's mySong variable is garbage collected (like any other local variable would be).
  3. _Constructor_ is a private function and not a method; I'm not entirely sure what this in that context will reference. You may end up creating a songs property on the global object (but I'd want to test that to be sure).
  4. As I mentioned earlier, when you call Array() with the new operator, it takes an optional argument that sets the initial length of the array. In this case, the interpreter will try to coerce mySong into a number (mySong is not added to the array!); when that fails it will simply return a new array with length = 0.

Instead, you're better off writing SongDatabase() like so:

function SongDatabase() {
    this.songs = [];
    // etc.
}

SongDatabase.prototype.loadSongs = function () {
    // load songs into `this.songs`
};

SongDatabase.prototype.saveSongs = function () {
    // save songs loaded into `this.songs`
};

The prototypal pattern may look strange, but its probably the best way to handle your use case. You'll still have direct access to then songs array (which may or may not be important), and by attaching the loadSongs and saveSongs functions to SongDatabase's prototype you ensure that those functions are shared.

相关问答

更多
  • 只是为了完整 function myFunc (method){ this.type = method; this.border = '20'; // take a reference to the current object var self = this; this.add = function(){ // some codes privateFunc(); } ...
  • 你的函数里面的this不一定和构造函数中的相同,它取决于你如何调用该函数。 例如,如果通过执行f()调用函数f ,则this === window ,如果它是对象xf()上的方法,则this === x 。 另见Function:call和Function:apply 。 解决这个问题的最简单方法是在构造函数中有一个局部变量(比如var me = this; )然后在内部函数中使用me而不是this ,因为它不会被覆盖。 如果您想了解更多信息,请阅读词法范围和闭包。 this inside your fun ...
  • 您可以像访问数组索引一样访问对象的属性,例如,您可以这样运行getElementById : document["getElementById"]("#myid"); 所以如果您事先知道该函数将成为哪个对象,您可以通过这种方式访问它。 全局范围中的函数是window对象的方法。 但是,如果散列可能包含#document.write()类的表达式,则必须进行一些解析。 它可以像这样工作 window.onload=function() { var urlhash = document.locatio ...
  • JSON将数字作为字符串提供,因此硬编码值的工作原理。 使用parseInt()更改为生成的数字和图表。 JSON was delivering numbers as strings hence why hard coded values were working. Used parseInt() to change to numbers and chart generated.
  • 您可以使您的函数在全局范围内可访问,并仍然参考创建它的范围内的变量。 只需在窗口范围内创建并分配它,而不是将其定义为: function autoSave() { // ... code ... } 将其声明为: window.autoSave = function() { // .... code .... } 你现在可以在任何地方调用它(只要initStage方法已经被调用来声明它,当然)。 You can make your function globally accessible ...
  • 你应该在你的main.js中像这样传递窗口对象 (function(w){ w.myFunction = function(){ alert(1); } })(window); “()”中的function关键字后面的变量是函数内部传递的参数的别名,而封装函数末尾的“()”内的变量是要传递的实际变量。 DEMO: http : //codepen.io/anon/pen/aOgZdB - 已经在IE中试用过了。 另一件事,我认为你可以直接将函数绑定到窗口,而不需要将它放在封装的函数中,如: ...
  • 您可以使用get_defined_vars()来获取调用get_defined_vars()的范围内的所有变量。 You can use get_defined_vars() to get all the variables within the scope that get_defined_vars() is called.
  • 我看到有人在JavaScript中使用“Java”。 :) 关于JavaScript你应该了解的几件事: 在JavaScript中,数组不像其他语言那样工作。 它们更像是字典,然后用C或Java称为数组; 它们没有更高的内存效率或更快; 没有预先分配; 在低级实现中没有任何缺陷等。 JavaScript数组只是一个方便(但有用!)的结构,用于保存命令命令数据。 可以使用new Array(length)表达式或简单的文字表达式[]创建new Array(length) 。 通常,您需要使用数组文字[] 。 ...
  • 首先,ID必须是唯一的。 你有两个名为#num1 id。 输入标签也是自动关闭的,因此不需要 。 看起来应该更像这样。 此外,您可以将其简化为一个,而不是为每个产品定义两个变量。 第三,您将JavaScript与jQuery混合使用。 坚持使用一个是最好的做法。 这是一个jQuery解决方案。 $('.success').on('click', function() { var product1 = $("#num1").val() * 100; var product2 = $ ...
  • 肯定很糟糕。 通过使用Angular $http或$resource的API实现RESTful体系结构并从Node.js请求数据。 对于常规的服务器到客户端和双向通信,Angular是错误的答案,因为它基于HTTP 。 在这种情况下,您需要使用WebSocket 。 It sure sucks. Implement RESTful architecture and request data from Node.js via an API using Angular $http or $resource. F ...

相关文章

更多

最新问答

更多
  • 获取MVC 4使用的DisplayMode后缀(Get the DisplayMode Suffix being used by MVC 4)
  • 如何通过引用返回对象?(How is returning an object by reference possible?)
  • 矩阵如何存储在内存中?(How are matrices stored in memory?)
  • 每个请求的Java新会话?(Java New Session For Each Request?)
  • css:浮动div中重叠的标题h1(css: overlapping headlines h1 in floated divs)
  • 无论图像如何,Caffe预测同一类(Caffe predicts same class regardless of image)
  • xcode语法颜色编码解释?(xcode syntax color coding explained?)
  • 在Access 2010 Runtime中使用Office 2000校对工具(Use Office 2000 proofing tools in Access 2010 Runtime)
  • 从单独的Web主机将图像传输到服务器上(Getting images onto server from separate web host)
  • 从旧版本复制文件并保留它们(旧/新版本)(Copy a file from old revision and keep both of them (old / new revision))
  • 西安哪有PLC可控制编程的培训
  • 在Entity Framework中选择基类(Select base class in Entity Framework)
  • 在Android中出现错误“数据集和渲染器应该不为null,并且应该具有相同数量的系列”(Error “Dataset and renderer should be not null and should have the same number of series” in Android)
  • 电脑二级VF有什么用
  • Datamapper Ruby如何添加Hook方法(Datamapper Ruby How to add Hook Method)
  • 金华英语角.
  • 手机软件如何制作
  • 用于Android webview中图像保存的上下文菜单(Context Menu for Image Saving in an Android webview)
  • 注意:未定义的偏移量:PHP(Notice: Undefined offset: PHP)
  • 如何读R中的大数据集[复制](How to read large dataset in R [duplicate])
  • Unity 5 Heighmap与地形宽度/地形长度的分辨率关系?(Unity 5 Heighmap Resolution relationship to terrain width / terrain length?)
  • 如何通知PipedOutputStream线程写入最后一个字节的PipedInputStream线程?(How to notify PipedInputStream thread that PipedOutputStream thread has written last byte?)
  • python的访问器方法有哪些
  • DeviceNetworkInformation:哪个是哪个?(DeviceNetworkInformation: Which is which?)
  • 在Ruby中对组合进行排序(Sorting a combination in Ruby)
  • 网站开发的流程?
  • 使用Zend Framework 2中的JOIN sql检索数据(Retrieve data using JOIN sql in Zend Framework 2)
  • 条带格式类型格式模式编号无法正常工作(Stripes format type format pattern number not working properly)
  • 透明度错误IE11(Transparency bug IE11)
  • linux的基本操作命令。。。