Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/396.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
关于JavaScript如何工作的几个问题_Javascript_Oop_Function_Prototype - Fatal编程技术网

关于JavaScript如何工作的几个问题

关于JavaScript如何工作的几个问题,javascript,oop,function,prototype,Javascript,Oop,Function,Prototype,我最近一直在深入研究JavaScript以完全理解该语言,并且有一些我似乎找不到答案的烦人问题(特别是处理面向对象编程) 假设以下代码: function TestObject() { this.fA = function() { // do stuff } this.fB = testB; function testB() { // do stuff } } TestObject.prototype

我最近一直在深入研究JavaScript以完全理解该语言,并且有一些我似乎找不到答案的烦人问题(特别是处理面向对象编程)

假设以下代码:

function TestObject()
{
    this.fA = function()
    {
        // do stuff
    }

    this.fB = testB;

    function testB()
    {
        // do stuff
    }
}

TestObject.prototype = {
    fC : function 
    {
        // do stuff
    }
}
功能
fA
fB
之间有什么区别?他们的行为范围和潜在能力完全相同吗?这仅仅是惯例,还是一种技术上更好或更恰当的方法

如果在任何给定的时间只有一个对象实例,那么向原型中添加一个函数(如
fC
)是否值得?这样做有什么好处吗?原型是否仅在处理对象或继承的多个实例时才真正有用

从技术上讲,向原型中添加方法的“正确”方法是什么,就像我上面所说的,还是每次调用
TestObject.prototype.functionName=function(){}


我希望尽可能保持我的JavaScript代码干净易读,但我也对语言中对象的适当约定非常感兴趣。我来自Java和PHP背景,我不想对JavaScript的工作原理做任何假设,因为我知道基于原型的JavaScript非常不同。

我回答第一部分:没有区别,当您声明函数不是变量时,它的声明会在块中上升,所以

...
func();
...    
function func () { ... }
等于

var func = function () { ... };
...
func();
...
function TestObject () {
    var testB = function () { // do stuff };    
    this.fA = function () { // do stuff };
    this.fB = testB;
}
所以你的代码

function TestObject () {
  this.fA = function() { // do stuff };   
  this.fB = testB;    
  function testB() { // do stuff }
}
等于

var func = function () { ... };
...
func();
...
function TestObject () {
    var testB = function () { // do stuff };    
    this.fA = function () { // do stuff };
    this.fB = testB;
}

fA
fB
实际上是相同的,这只是惯例问题

如果一个对象只有一个实例,我甚至不会使用构造函数,而只使用对象文本,例如:

var o = {
   fA: function () { ... },
   fB: function () { ... },
   fC: function () { ... }
};
至于将其添加到实例或原型中,如果您只有一个实例,但如我所说,使用文本,则实例比将其添加到原型中的效率略高

我避免在构造函数中声明函数,因为每次调用构造函数都会创建表示每个函数的新对象。这些对象不是很大,如果创建了许多对象,它们往往会累加起来。如果可以将这些函数移动到原型中,那么这样做会更加高效

至于增加原型,我赞成

TestObject.prototype.functionName = function () { };
但这是一个偏好的问题。我喜欢上面的内容,因为无论是扩展原型还是创建初始原型,它看起来都是一样的

功能fA和fB之间有什么区别

实际上,什么都没有。函数表达式(fA)和函数声明(fB)之间的主要区别在于创建函数的时间(声明的函数在执行任何代码之前可用,而函数表达式在表达式实际执行之前不可用)。还有各种各样的怪癖,你可能会偶然发现

在这个例子中,我会使用一个函数表达式,因为声明一个函数表达式,然后分配结果似乎有点抽象。但这两种方法都没有“对”或“错”

如果在任何给定的时间只有一个对象的实例,那么在原型中添加一个函数(比如fC)是否值得呢

不是。几乎每个继承的人都会发现普通对象通常更简单,因此“更好”。原型继承对于修补内置对象非常方便(例如,在缺少的地方添加Array.Prototype.each)

从技术上讲,向原型添加方法的“正确”方式是什么

没有。用其他对象替换默认原型似乎有点浪费,但是分配一个由文本创建的对象可能更整洁,更易于阅读。对于一个或两个作业,我会使用:

 Constructor.prototype.method = function(){…}
但是对于很多方法,我会使用对象文字。有些甚至使用经典的扩展函数并执行以下操作:

myLib.extend(Constructor.prototype, {
    method: function(){…}
});
如果已经定义了一些方法,那么这有助于添加这些方法

看看一些库,决定你喜欢什么,一些混合搭配。做任何适合特定情况的事情,通常只需获得足够多的代码,使所有代码看起来都一样,然后无论您选择了什么模式,它都会看起来整洁

还有任何权威的JavaScript风格指南或文档吗 关于JavaScript如何在低级别上运行

该死,任何javascript程序员都不应该错过。这是一本奇妙的书,深入到了深处。它解释了对象、类模拟、函数、作用域等等。它也是一个JS参考

从技术上讲,向 原型的方式,我有以上或调用 每次都是TestObject.prototype.functionName=function(){}

至于定义类的方法,我建议看一下各种JS MVC框架(比如Spine.JS,它是轻量级的)。您不需要它们的全部,只需要它们的类仿真库。其主要原因是,JS没有类的概念,而是纯粹由对象和原型组成。另一方面,类可以被完美地模拟(请不要使用单词simulated,因为它缺少一些东西)。由于这需要程序员进行一些训练,因此最好有一个类仿真库来完成这项工作并使代码更干净

程序员应该期望的类仿真库的标准方法有:

// define a new Class
var AClass = Class.create({
   // Object members (aka prototype), 
   // usually an initialize() method is called if it is defined 
   // as the "constructor" function when a class object is created
}, {
   // Static members
}); 

// create a child class that inherits methods and attributes from parent
var ChildClass = AClass.extend({
   // Child object members
},{
   // Child static members
}); 

AClass.include({
   // Object amendments (aka mixin), methods and attributes 
   //   to be injected to the class object
},{
  // Statics amendments, methods and attributes to be 
  //  injected as class static members
});


// check object type
var aObj = new AClass();
aObj instanceof AClass; //  true
aObj instanceof ChildClass; //  false


var cObj = new ChildClass();
cObj instanceof AClass; //  true
cObj instanceof ChildClass; //  true

Javascript!=面向对象。正如您(正确地!)所观察到的,Javascript可以更好地描述为一种“原型”语言。强,强推荐书:。嗯…好问题,问错地方了。你最好在paulsm4中提出这样的问题:我明白这一点,为了完整起见,我也正试图从这个角度理解JavaScript。谢谢