JavaScript:通过构造函数和对象文字创建对象之间的差异是什么?

时间:2015-08-22 22:03:21

标签: javascript

这两个人声明之间的主要区别是什么?

通过构造函数:

var Person = function (name, age) {
    this.name = name;
    this.age = age;
    this.setName = function (name) {
        this.name = name;
    };
    this.setAge = function (age) {
        this.age = age;
    };
};

var bob = new Person('Bob', 15);

通过对象文字:

var defaultPerson = {
    name: '',
    age: '',
    setName: function (name){
        this.name = name;
    },
    setAge: function(age){
        this.age = age;
    }
};

defaultPerson.setName('Fill');
defaultPerson.setAge(15);

是否对这两个创建的对象施加了一些限制?

5 个答案:

答案 0 :(得分:3)

使用构造方法,您可以创建多个实例(非常相当于一个类):

var person1 = new Person('a',12);
var person2 = new Person('b',13);

而另一种方式只会创建一个类的实例。

var person1 = {
  // blah
};

对于person2,您需要创建一个新对象:

var person2 = {
  // blah
};

在ctor方式中你也可以:
1.运行代码 2.传递参数。
3.拥有原型并支持继承\扩展对象。

答案 1 :(得分:2)

这是关于Javascript和继承方法中的OO的广泛问题。我无法在帖子的答案中覆盖它,你应该进行一些搜索和阅读,但这里有一些要考虑的要点:

  1. 第一个叫做Function Constructor,通常第一个字母按约定大写。现在,让我们假设你想要为'new'创建的对象添加一些共享方法Person:然后你将Person()的.prototype属性设置为一个包含这种共享方法的对象。
  2. 在第二种方法中,您刚刚创建了一个普通对象并使用了它的方法。但我假设你真正想要做的是将其作为原型来创建其他对象。请考虑以下代码:

    var fill = Object.create(defaultPerson);
    // fill will be created and its internal prototype is set to the defaultPerson object.
    
  3. 第二种方法通常被称为Pure Prototypal Inheritance,其中一些包括我自己,发现它对Javascript更自然。

  4. 第一种方法是对经典OOP语言中的构造函数的模仿。现在在ES6(2015)中通过添加关键词'calss,extends'来进一步加强;

  5. 毕竟;两者都是在Javascript中创建对象和实现继承的有效方法。做出选择并坚持方便。

  6. 祝你好运,希望这会有所帮助。

答案 2 :(得分:0)

主要有三个不同之处:

使用文字...

创建对象时
  1. .__proto__属性设置为Object.prototype
  2. .constructor设置为function Object(){...}
  3. 它不是使用构造函数创建的,因此创建类似的对象需要重复。
  4. 但是,如果您运行此代码......

    function a(){}
    var obj = new a();
    
    //then
    
    obj.constructor  == a;
    obj.__proto__ == a.prototype;
    

    我能想到的另一个实际差异:

    var o = {
         a : 1,
         b : this.a + 2
    };
    

    在这种情况下,b将是未定义的,给出错误或归因于现在引用的this.a。除了它之外的一切都不会是1。在使用构造函数方法的情况下,这将起作用......

    function Math() {
        this.a = 1;
        this.b = this.a +2 ;
    }
    var m = new Math();
    

答案 3 :(得分:0)

如果你想在js中应用OOP,那么使用protype比使用构造函数更好。因为js对象会将它的属性传递给它的孩子作为原型。

答案 4 :(得分:0)

函数构造函数创建一个新对象,你必须做三件额外的事情来吸收传统的类/继承设计:

  1. 调用基类:base.call(this,props ...);
  2. 扩充原型:obj.prototype.func = function(){};
  3. 重新分配构造函数
  4. ECMA6将引入新的语法,如extend和Class,但JS是一种原型语言。这只是意味着每次你创建一个对象var o = {};它不是一个真正的空对象,它没有属性,而是坐在编译器的黑暗水域下面,存在一个称为原型的辅助对象,这里编译器链接回另一个对象。

    当您要求编译器获取值时,例如console.log(this.x)它首先查看对象拥有属性,如果它能找到它,它会装饰一个通气管并将其头部浸入温水中以搜索对象原型。如果它不在那里,编译器必须穿上它的湿衣服深入潜入黑暗的水域。如果编译器现在位于海床上,则它不再搜索,而是在最低级别的对象Object上搜索。然后,编译器将咳嗽并且向后spl undefined,因为它正在通过深渊再次呼吸它。

    因此,您的属性和函数越接近对象的直接上下文,代码执行得越好。如果您尝试链接许多原型,编译器将在潜水和重新铺设之后获得弯曲。

    在JS中创建类时,您将创建实例属性并设置原型:

    var Cat = function() {
        this.age = 3;
        this.colour = 'black';
    };
    
    Cat.prototype.age = function() { console.log(this.age); };
    

    使用new关键字创建一个空白对象并将上下文设置为this,因此在Cat中我们只是增加当前上下文的属性,例如this.age = 3;

    编译器已经知道Cat.prototype,这些函数链接到您的对象,而不是逐字复制到您的对象。

    创建对象的new方式很笨拙,以下内容包含原型委派;称之为mixins,扩展,继承或其他什么,重点是我们可以用其他对象扩充对象并将函数放在原型上,所以所有实例都可以看到它们。

    var manufacturer = {
        id:'manufacturer',
        constructor : function (args) {
            this.boss = args.boss || 'Bernie Ecclestone';
          this.country = args.country || 'UK';    
            return this;
        }
    };
    
    var vehicle = {
        id:'vehicle',
        constructor : function (args) {
            this.colour = args.colour || 'blue';
          this.wheels = args.wheels || 2;     
            extend.call(this, manufacturer, args);
            return this;
        }
    };
    
    var driver = {
        id:'driver',
        constructor : function (args) {
            this.name = args.name || 'John';
            return this;
        },
        info : function () { console.log(this.name); }
    };
    
    var engine = {
        id:'engine',
        constructor : function (args) {
            this.type = args.type || 'V6';
            this.fuel = args.fuel || 'petrol';
            return this;
        },
        tune : function () { 
            this.type = 'super-charged';
            this.fuel = 'ethanol';
            console.log('Car now ' + this.type + ' with ' + this.fuel); 
        }
    };
    
    var car = {
        id:'car',
        constructor : function (args) {       
            extend.call(this, vehicle, args);
          extend.call(this, driver, args); 
            extend.call(this, engine, args);   
            return this;
        },
        info : function () { 
            console.log('boss: ' + this.vehicle.manufacturer.boss);
            console.log('country: ' + this.vehicle.manufacturer.country);
            console.log('driver: ' + this.driver.name);
            console.log('colour: ' + this.vehicle.colour);
          console.log('wheels: ' + this.vehicle.wheels);
          console.log('type: '   + this.engine.type);
          console.log('fuel: '   + this.engine.fuel);
            console.log('\n');
      }
    };
    
    function extend(proto, args){
      this[proto.id] = Object.create(proto);
      proto.constructor.call(this[proto.id], args);
    }
    
    var ferrari = Object.create(car).constructor({
        boss: 'Maurizio Arrivabene',
        country:'Italy',
        name: 'Steve', 
        colour: 'red', 
        wheels: 4, 
        type:'100cc', 
        fuel:'diesel'
    });
    
    var lotus = Object.create(car).constructor({
        name: 'Jenson Button'
    });
    
    var mclaren = Object.create(car).constructor({
      type:'hybrid',
        fuel:'battery/petrol'
    });
    
    ferrari.engine.tune();
    ferrari.info();
    /*
    Car now super-charged with ethanol
    boss: Maurizio Arrivabene
    country: Italy
    driver: Steve
    colour: red
    wheels: 4
    type: super-charged
    fuel: ethanol
    */
    
    lotus.info();
    /*
    boss: Bernie Ecclestone
    country: UK
    driver: Jenson Button
    colour: blue
    wheels: 2
    type: V6
    fuel: petrol
    */
    
    mclaren.info();
    /*
    boss: Bernie Ecclestone
    country: UK
    driver: John
    colour: blue
    wheels: 2
    type: hybrid
    fuel: battery/petrol
    */