Javascript创建对象-多种方法,有什么区别吗?

Javascript创建对象-多种方法,有什么区别吗?,javascript,javascript-objects,Javascript,Javascript Objects,我已经看到了一些在javascript中实例化对象的不同方法,想知道各种方法的优缺点,以及为什么要使用一种方法而不是另一种方法 方法1 var obj = { prop: value, . . . } 方法一是标准方法,没有什么新的:) 方法2 var obj = new function() { var prop1 = value1; var fn1 = function() { }; . . . th

我已经看到了一些在javascript中实例化对象的不同方法,想知道各种方法的优缺点,以及为什么要使用一种方法而不是另一种方法


方法1

var obj = {
    prop: value,
    .
    .
    .
}
方法一是标准方法,没有什么新的:)

方法2

var obj = new function() {
    var prop1 = value1;
    var fn1 = function() {
    };
    .
    .
    .

    this.prop2 = value2;
    .
    .
    .
}();
关于函数方法,我想将这种方法与方法3进行比较。函数方法主要用于封装(正确吗?)

方法3

var obj = (function() {
    var prop1 = value1;
    var fn1 = function() {
    };
    .
    .
    .

    return {
        prop2: value2,
        .
        .
        .
    }
})();
对于这种方法,我不太明白其使用背后的原因。它与方法2有何不同?两者都可以用来封装逻辑

是不是这样我们可以传入参数,这样我们就可以处理任何潜在的冲突??例如jquery的
$
语法-但您也可以使用方法2来实现这一点

谢谢


编辑:


我知道方法1和3是相似的(因为它们都返回对象),但是方法3也创建了一个闭包。哪种方法2也可以


这就是我问题的基础。实际上,2和3都创建闭包,但它们之间有什么区别。

对于一次性对象,方法2和方法3之间没有太大区别。(如果你给方法2中使用的函数命名,你会定义一个可重用的构造函数。)我的印象是,方法3更常用于这些情况,但我看不出它们之间有什么区别

应该注意的是,方法2和方法3都可以采用以下参数:

var approach2Obj = new function(formalArg) {
    var privateProp = ...;
    this.publicProp = ...;
    // more constructor logic
)(actualArg);

var approach3Obj = (function(formalArg) {
    var privateProp = ...;
    // more creation logic
    return {
        publicProp : ...;
    };
}(actualArg));

另外,两者之间的一个区别(可能是唯一的区别)是
approach 2obj.constructor
approach 3obj.constructor
将是不同的
approach 3Obj.constructor
将是相同的
Object
,而
approach 2Obj.constructor
将是匿名函数。

第一种和第三种方法几乎相同,在某种程度上它们都创建了一个对象文本,它是
Object
类的直接子类。它们之间的区别在于,在第三种方法中,您可能会对属性进行某种封装:

var obj = (function() {
    var prop = {};

    return {
        prop2: function(){ return prop };
    }
})();

性能明智,您可能会认为第三种方法创建了闭包,而第一种方法不关闭。p> 然而,在第二种方法中,您仅仅是从一个匿名类创建一个新对象,该类不是

对象
类的直接子类

第二种方法的正确形式是(至少这是ecma标准):

方法2和方法3之间的区别只是它们的继承链: (假设obj2来自第二进近,obj3来自第三进近)

obj2是从匿名类本身创建的:

obj2.__proto__.__proto__ == Object.prototype;  // true (there's 2 level of inheritance here)

您的问题应该是两种方法,因为方法3与方法1完全相同,只有通过自执行函数才能创建方法

关于区别,当你创建一个类似于方法1的对象时,你可以把它想象成一个只有静态函数的对象,就像在java中一样。因此,它始终处于活动状态,并且您不使用它创建实例(类似于singleton)-因此,当您创建此对象时:

var obj = {
    prop: value,
    func: function(){
     alert(this.prop);
    }
};
您可以立即拨打:

obj.prop = 'something else';
obj.func();
方法2(没有新的注释)是一个可以创建实例的经典对象-make inherit(使用js“技巧”)等等:

function Person(firstName,lastName){ // or var Person = function(...
   this.firstName = firstName;
   this.lastName= lastName;

   this.getFullName = function(){
      return this.firstName + ' ' + this.lastName;
   }
}

//use
var person1 = new Person('yair','lapid');
var person2 = new Person('Naftali','Bennet');

you can put it in an array etc...
var arr = [person1,person2, new Person('shelly','yekimovits')];

方法1
这是一个单一的对象,没有类,如果它很复杂的话,定义起来也不容易

var obj = {
   prop: value
}
方法2
非匿名函数。它将从一个“类”中创建一个对象,normale该函数保存为一个类名,可以轻松创建多个相同类型的对象,如下所示:

var Bycicle= function() {
    var prop1 = value1;

    this.prop2 = value2;
}
var obj1 = new Bycicle(),
    obj2 = new Bycicle();
方法3
一个匿名函数,函数外部的变量不能干扰函数内部的变量:

var a = 10;
var obj = (function() {
    alert(a); // Alerts undefined
    var prop1 = value1;
    alert(prop1); // alerts the value of value1
    return {
        prop2: value2;
    }
})(); // Within the () you can pass arguments to the anonymous function.
x = new function() { alert(1) };
y = new x.constructor; // shows the message too
有关匿名函数的详细信息:

其他方法
还有一个
Object.create()
和一个
newobject()
来创建新对象,这两个方法与方法1相同

结论

最后,除了第三个对象外,对象始终是相同的,因为它是匿名的。

为了理解方法2,读者需要了解一些关于新关键字工作方式的相当技术性的东西。具体来说,它将实际调用匿名函数作为构造函数,而不是实例化新函数对象并将其转储到obj变量中


为了理解方法3,读者只需要理解生活模式。在过去两年中,这种模式在javascript代码中变得非常常见,这可能就是为什么该版本更常用的原因

这两个版本都用于生成封装,并且这两个版本都需要了解复杂的语言特性。然而,方法三所需的语言特征比理解方法二所需的语言特征更为人所知。这就是为什么方法三在野外更常用。

在方法2和方法3中,结果对象的
构造函数
属性将不同

实际上,这意味着第二种方法允许您使用匿名构造函数实例化多个对象:

var a = 10;
var obj = (function() {
    alert(a); // Alerts undefined
    var prop1 = value1;
    alert(prop1); // alerts the value of value1
    return {
        prop2: value2;
    }
})(); // Within the () you can pass arguments to the anonymous function.
x = new function() { alert(1) };
y = new x.constructor; // shows the message too
最重要的答案是道格拉斯·克罗克福德(Douglas Crockford)的一句话,他在其中解释了为什么他认为第三种方法优于第二种方法。

还有:

var obj = Object.create({prop: ...});
这是通过设置原型来实现的。如果要让多个对象共享属性或方法,那么使用原型会更有效

var proto = {foo: function() {}},
    obj1 = Object.create(proto),
    obj2 = Object.create(proto),
    obj3 = {foo: function() {}},
    obj4 = {foo: function() {}};
在本例中,obj1和obj2共享一个在“proto”中定义的“foo”函数。同时,obj3和obj4都有自己的“foo”。如果您正在创建大量具有大量属性的对象,这可能会对内存产生很大影响
var person = new Object();  
person.name = "Diego";  
person.getName = function(){  
    return this.name;  
}; 
var person = {  
    person.name : "Diego",  
    person.getName : function(){  
        return this.name;  
    }  
} 
var newPerson=function(name){  
    var result = new Object();  
    result.name = name;  
    result.getName = function(){  
        return this.name;  
    };  
    return result;  
};  
var personOne = newPerson("Diego");  
var personTwo = newPerson("Gangelo");  
console.log(personOne.getName()); // prints Diego  
console.log(personTwo.getName()); // prints Gangelo
view plainprint?
var newPerson=function(name){  
    return {  
        person.name : name,  
        person.getName : function(){  
            return this.name;  
        };  
};  
var personOne = newPerson("Diego");  
var personTwo = newPerson("Gangelo");  
console.log(personOne.getName()); // prints Diego  
console.log(personTwo.getName()); // prints Gangelo  
function Person(name){  
        this.name = name;  
        this.getName = function(){  
            return this.name;  
        };  
};  
var personOne = new Person("Diego");  
console.log(personOne.getName()); // prints Diego  
console.log(personOne instanceOf Person); // prints true  
console.log(personOne.constructor === Person); // prints true  
console.log(personOne instanceOf Object); // prints true  
function Person(){};  
Person.prototype.name = "Diego";  
var personOne = new Person();  
var personTwo = new Person();  
console.log(personOne.constructor == Person); // prints true  
console.log(personOne.name); // prints Diego  
console.log(personTwo.constructor == Person); // prints true  
console.log(personTwo.name); // prints Diego  
function Person(name){  
        this.name = name;  
};  
Person.prototype.getName = function(){  
            return this.name;  
        };  
var personOne = new Person("Diego");  
var personTwo = new Person("Filippo");  
console.log(personOne.getName()); // prints Diego  
console.log(personTwo.getName()); // prints Filippo  
console.log(personOne.getName === personTwo.getName) //prints true 
var singleton = new function(){  
    this.name = "ApplicationName";  
};  
var person = {
  name: ['Bob', 'Smith'],
  age: 32,
  gender: 'male',
  interests: ['music', 'skiing'],
  bio: function() {
    alert(this.name[0] + ' ' + this.name[1] + ' is ' + this.age + ' years old. He likes ' + this.interests[0] + ' and ' + this.interests[1] + '.');
  },
  greeting: function() {
    alert('Hi! I\'m ' + this.name[0] + '.');
  }
};
function Vehicle(name, maker) {
  this.name = name;// Every function while executing has a reference         
            this.maker = maker;// to its current execution context called as this
}
let car1 = new Vehicle(’Fiesta’, 'Ford’);// New keyword with function turns function call into constructor call
let car2 = new Vehicle(’Santa Fe’, 'Hyundai’);

console.log(car1.name);    //Output: Fiesta
console.log(car2.name);    //Output: Santa Fe
let car = Object.create(Object.prototype,{
   name:{
     value: 'Fiesta',
     configurable: true,
     writable: true,
     enumerable: false
   },
   maker:{
     value: 'Ford',
     configurable: true,
     writable: true,
     enumerable: true
   }});
console.log(car.name)    //Output: Fiesta
class Vehicle {
 constructor(name, maker, engine) {
   this.name = name;
   this.maker =  maker;
   this.engine = engine;
 }
}

let bike1 = new Vehicle('Hayabusa', 'Suzuki', '1340cc');
let bike2 = new Vehicle('Ninja', 'Kawasaki', '998cc');

console.log(bike1.name);    //Output: Hayabusa
console.log(bike2.maker);   //Output: Kawasaki
var d = new Object();