2016-09-09 3 views
5

В чем разница между созданием объекта с помощью встроенного конструктора объектов и созданием объекта путем непосредственного вызова конструктора? Я всегда делал последнее, потому что мне не нужно было называть что-то вроде init() и чувствовал, что это правильно, но я все еще вижу обозначение объекта в коде других людей и задаюсь вопросом, есть ли другая разница. не посмотрев.Разница между различными объектными обозначениями

Пример:

window.fooModule = { 

    init: function() { 
    this.bar = "cee";  
    doStuff(); 
    }, 

    doStuff: function() { 
    ... 
    } 
} 

window.fooModule.init(); 

Пример2:

window.fooModule = new function(){ 
    this.bar = "Cee"; 

    this.doStuff = function() { 
    ... 
    } 


    this.doStuff(); 
} 
+1

Второй [не совсем ужасно] (http://stackoverflow.com/q/10406552/1048572) и никогда не должны использоваться – Bergi

+0

О, это глупо, сняли флаг, продолжайте! – Roberrrt

+0

Разница заключается в том, что 'doStuff()' в первом случае завершится с ошибкой имени. – deceze

ответ

1

В первой переменной нотации fooModel является объектом, созданным без вызова конструктора, во второй записи fooModel является объект, созданный с вызовом конструктора, как анонимные функции, так при использовании new функция конструктора ключевых слов вызывается и объект создается из своего прототипа (в этом примере прототип не объявлен, поэтому он является прототипом стандартного объекта).

Заключение

Использование второго обозначения, если Ваш объект должен вызвать некоторый код , когда создается, используйте первый, если нет.

Подробнее о втором нотации

Второе обозначение позволяет также используя локальные (частные) переменные и функции внутри конструктора, поскольку конструктор дает нам собственный объем.

var obj=new function(){ 

    var priv="Local scope variable"; 

    var method=function(){ 

    console.log("Local method"); 
    }; 

    this.doStuff=function(){ 

    //here local methods and variables can be used 
    }; 
}; 

Второе обозначение с конструктором и new чаще используется при стандартной функции конструктора декларации и декларации прототипа. Это правильный путь, если нам нужно создать более одного объекта. Методы и все общие свойства должны быть объявлены в прототипе не в конструкторе.

var ExampleClass=function(bar){ 

    //constructor 
    this.bar = bar; 
}; 

ExampleClass.prototype.doStuff=function(){ 

}; 

Создание такого объекта:

var a=new ExampleClass("A bar"); //a.bar is "A bar" 
var b=new ExampleClass("B bar"); //b.bar is "B bar" 

Объекты a и b имеют один и тот же прототип (это экономит память), но они могут иметь различные свойства, установленные в конструкторе.

оффтоп

В JavaScript так много возможностей для создания объектов, у меня есть третий пример того, как запустить код в первой записи:

window.fooModule = { 

    init: function() { 
    this.bar = "cee";  
    this.doStuff(); 

    return this;//return this 
    }, 

    doStuff: function() { 

    } 
}.init();//run init after object notation 

я создаю объект и запустить инициализации в одно время.

+0

Ваша оценка правильная, но я не согласен с вашим заключением. Нужно ** никогда не использовать вторую нотацию **. Если вам нужно выполнить некоторый код во время создания, используйте IIFE (как в шаблоне модуля). – Bergi

+0

@Bergi Я добавил дополнительную информацию –

+0

Спасибо, но я хочу сказать, что 'new' следует использовать только при создании нескольких экземпляров и никогда не для одного объекта, даже если есть код, который должен быть выполнен. – Bergi

-1

пусть первый пример возврата obj1 и второй пример возврата obj2

obj1 будет [[Prototype]] является объектом. Этот объект имеет свойство конструктора: "function Object()"

obj2 будет иметь [[Prototype]] объект.Этот объект имеет свойство конструктора: анонимная функция.

Путь в 2-ом примере, как правило, используется для достижения то, что мы называем «синглтон»

Bonus: Этот материал легко запутаться, но если вы хотите копать глубже, вот хороший пост для вас

https://zeekat.nl/articles/constructors-considered-mildly-confusing.html

+1

Первый шаблон также создает одноэлементный объект. – Bergi

+0

Что вы подразумеваете под "* [[Prototype]] является объектом *"? И вы предлагаете, чтобы результат не был другим? – Bergi

+0

на javascript, вы не можете напрямую обращаться к прототипу объекта. Однако вы можете получить доступ к прототипу функции. [[Prototype] - это именно то, как я использую, чтобы упомянуть о недоступном прототипе этого объекта и легко сравнивать с доступным прототипом функции – Khoa

-1

есть объекты и есть объект определения прототипы. Ни один из ваших примеров не является объектом определениями прототипов.

window.fooModule = function(bar){ 
    this.bar = bar; 

    (this.doStuff = something => { 
    console.log(this.bar,'is doing', something || 'something'); 
    })(); 
}; 

[a,b]= [new fooModule('a'), new fooModule('b')]; 

Если вы просто хотите создать объект, то вы можете пропустить оператор new и this.

(window.fooModule = { 
    bar : 'Cee', 
    doStuff : something => { 
    console.log(foo.bar,'is doing', something || 'something'); 
    }}).doStuff(); 
+0

Каким будет определение объекта? – Bergi

+0

Прототип объекта. –