Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/368.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_Object_Coding Style - Fatal编程技术网

Javascript对象定义技术及其优缺点

Javascript对象定义技术及其优缺点,javascript,object,coding-style,Javascript,Object,Coding Style,在Javascript中定义可重用对象的基本方法是什么?我说可以重用以排除单例技术,例如直接用对象文字符号声明变量。我在某个地方看到,克罗克福德在他的书中定义了四种这样的方式,但我宁愿不买一本书来获取这些简短的信息 以下是我熟悉的方法: 使用this,并使用new构造(我认为这称为经典?) 使用原型,这是相似的 function Foo() { var private = 3; } Foo.prototype.add = function(bar) { /* can't access

在Javascript中定义可重用对象的基本方法是什么?我说可以重用以排除单例技术,例如直接用对象文字符号声明变量。我在某个地方看到,克罗克福德在他的书中定义了四种这样的方式,但我宁愿不买一本书来获取这些简短的信息

以下是我熟悉的方法:

  • 使用
    this
    ,并使用
    new
    构造(我认为这称为经典?)

  • 使用原型,这是相似的

    function Foo() {
        var private = 3;
    }
    Foo.prototype.add = function(bar) { /* can't access private, correct? */ }
    
  • 返回文本,不使用
    this
    new

    function Foo() {
        var private = 3;
        var add = function(bar) { return private + bar; }
        return {
            add: add
        };
    }
    
    var myFoo = Foo();
    

我能想到这些相对较小的变化,可能在任何重大方面都不重要。我缺少什么款式?更重要的是,每种方法的优缺点是什么?是否有一个推荐的方法可以坚持,或者这是一个偏好问题和一场圣战?

原型方法没有每个对象实例的开销,只有add函数的每个类的开销。这就是我不喜欢其他两种方法的原因。

这主要是偏好的问题。没有一种方法可以制作鸡肉面条汤,而统一的物体也是同样的方法

我不使用这三种方法中的任何一种,尽管它们都是为自己的目的而工作的。我使用一个名为Object:deploy的自定义函数,并像这样使用它

var a = { hey: 'hello' },
    b = {}.deploy(a);

console.log(b.hey); // 'hello'
使用
prototype
对大多数人来说是最好的,因为它具有自动滴流功能

function A() {};
A.prototype.hello = "Hey";

var a = new A();
console.log(a.hello); // 'Hey'

A.prototype.hello = "Hello";

console.log(a.hello); // 'Hello'
与流行的观点相反,您可以在
prototype
中使用私有变量

function Hello() {};

(function () {
    var greeting = "Hello";

    Hello.prototype.greet = function () { return greeting };
}).apply(this);
但是,尽管这是可能的,但通常做得更好

function Hello() {};
Hello.prototype.greeting = "Hello";
Hello.prototype.greet = function () { return this.greeting };

使用原型。从构造函数返回特定对象会使它们成为非构造函数,将方法分配给
this
会降低继承的便利性

返回对象文本 优点:

  • 如果一个人忘记了
    new
    ,他们仍然会得到该对象

  • 您可以创建真正私有的变量,因为构造函数中定义的对象的所有方法都共享其作用域

缺点:

  • 它不是一个真正的构造函数。向其原型添加内容不会更改返回的对象,
    new
    或no
    new
    <代码>新的Foo()实例Foo也会导致
    false
使用
原型
优点:

  • 您使构造函数保持整洁

  • 这是JavaScript的标准操作方式,所有内置构造函数都将其方法放在原型上

  • 继承变得更容易、更正确;您可以(也应该)使用
    Object.create(ParentConstructor.prototype)
    而不是
    newparentconstructor()
    ,然后从
    构造函数中调用
    ParentConstructor
    。如果你想重写一个方法,你可以在原型上完成

  • 创建对象后,可以“修改”对象

  • 您可以扩展您无权访问的构造函数的原型

缺点:

  • 它可能会变得有点过于冗长,如果您想更改函数的名称,您也必须更改添加到原型中的所有函数。(或者将原型定义为一个大对象文字,并为
    构造函数
    提供兼容的属性描述符)

  • 它们不共享特定于实例的作用域,因此不能真正拥有私有变量

在构造函数中分配给此.
优点:

  • 您可以使用闭包,从而使用私有成员变量
缺点:

  • 没有鸭子打字;不能使用任何旧对象直接从原型调用方法。例如,
    Array.prototype.slice.call(collectionLikeObject)
第二种方法(prototype)与Python等其他语言中的标准类更为相似,因为您有一个通用的“prototype”对象,所有实例都共享该对象。要比较第一种和第二种方法:

  • 在方法1中,每次调用“
    newfoo()
    ”,您都在创建一个全新的对象并插入所有方法。这不是很节省时间或空间,因为每个Foo实例都有自己的所有方法表。您可以通过创建两个Foo对象并询问
    foo1.add==foo2.add
    (false)来测试这一点。方法3与此非常相似;我不确定方法1和方法3之间的语义差异(如果有的话)是什么
  • 在方法2中,您已经设置了一个包含所有方法的共享原型对象。如果你问
    foo1.add==foo2.add
    ,你会得到正确答案。这更节省空间和时间。它还允许您在创建实例后向原型中添加更多方法,它们将看到新方法
正如您所说,方法2的问题在于您无法访问私有成员。但您仍然可以向对象本身添加非私有成员,并使用prototype方法访问这些成员:

function Foo() {
    this.private = 3;
}
Foo.prototype.add = function(bar) { return this.private + bar }

需要注意的是,
foo.private
在外部可见。

不要忘记继承。总有一天你会需要的。为了组织继承,最好的方法是组合技术:

function Foo() {
    this.array = [1, 2, 3];
    this.add = function(bar) { return private + bar; }
}

Foo.prototype.add = function(bar) {  }

var myFoo = new Foo();
在构造函数中设置字段有助于避免子对象修改它们。
将方法设置为原型比每次在构造函数中都要快。

var dinner=“鸡肉面条汤”
原型
示例中,
.apply(此)
部分是不必要的,它不起任何作用,可以用空的呼叫接线员
()
替换。匿名函数在全局范围内调用,其
this
已经是全局对象。无论如何,它的
这个
没有任何用途。@RobG我的答案,我的编码风格。@RobG它实际上是必要的
function Foo() {
    this.array = [1, 2, 3];
    this.add = function(bar) { return private + bar; }
}

Foo.prototype.add = function(bar) {  }

var myFoo = new Foo();