Javascript 1.9.3 / ECMAScript 5引入了Object。这是Douglas Crockford等人长期以来一直倡导的。我如何在下面的代码替换新的对象。创建?

var UserA = function(nameParam) {
    this.id = MY_GLOBAL.nextId();
    this.name = nameParam;
}
UserA.prototype.sayHello = function() {
    console.log('Hello '+ this.name);
}
var bob = new UserA('bob');
bob.sayHello();

(假设MY_GLOBAL。nextId存在)。

我能想到的最好的是:

var userB = {
    init: function(nameParam) {
        this.id = MY_GLOBAL.nextId();
        this.name = nameParam;
    },
    sayHello: function() {
        console.log('Hello '+ this.name);
    }
};
var bob = Object.create(userB);
bob.init('Bob');
bob.sayHello();

似乎没有任何优势,所以我想我没有得到它。我可能太新古典主义了。我应该如何使用Object。创建创建用户“bob”?


当前回答

我更喜欢结束的方法。

我还在用new。 我不用object。create。 我不用这个。

我仍然使用new,因为我喜欢它的声明性。

考虑简单的继承。

window.Quad = (function() {

    function Quad() {

        const wheels = 4;
        const drivingWheels = 2;

        let motorSize = 0;

        function setMotorSize(_) {
            motorSize = _;
        }

        function getMotorSize() {
            return motorSize;
        }

        function getWheelCount() {
            return wheels;
        }

        function getDrivingWheelCount() {
            return drivingWheels;
        }
        return Object.freeze({
            getWheelCount,
            getDrivingWheelCount,
            getMotorSize,
            setMotorSize
        });
    }

    return Object.freeze(Quad);
})();

window.Car4wd = (function() {

    function Car4wd() {
        const quad = new Quad();

        const spareWheels = 1;
        const extraDrivingWheels = 2;

        function getSpareWheelCount() {
            return spareWheels;
        }

        function getDrivingWheelCount() {
            return quad.getDrivingWheelCount() + extraDrivingWheels;
        }

        return Object.freeze(Object.assign({}, quad, {
            getSpareWheelCount,
            getDrivingWheelCount
        }));
    }

    return Object.freeze(Car4wd);
})();

let myQuad = new Quad();
let myCar = new Car4wd();
console.log(myQuad.getWheelCount()); // 4
console.log(myQuad.getDrivingWheelCount()); // 2
console.log(myCar.getWheelCount()); // 4
console.log(myCar.getDrivingWheelCount()); // 4 - The overridden method is called
console.log(myCar.getSpareWheelCount()); // 1

反馈鼓励。

其他回答

简介:

object. create()是一个Javascript函数,它接受2个参数并返回一个新对象。 第一个参数是一个对象,它将是新创建对象的原型 第二个参数是一个对象,它将是新创建对象的属性

例子:

Const proto = { Talk: () => console.log('hi') } Const props = { 年龄:{ 可写:没错, 可配置:没错, 价值:26 } } let Person = Object。创建(原型、道具) console.log (Person.age); Person.talk ();

实际应用:

The main advantage of creating an object in this manner is that the prototype can be explicitly defined. When using an object literal, or the new keyword you have no control over this (however, you can overwrite them of course). If we want to have a prototype The new keyword invokes a constructor function. With Object.create() there is no need for invoking or even declaring a constructor function. It can Basically be a helpful tool when you want create objects in a very dynamic manner. We can make an object factory function which creates objects with different prototypes depending on the arguments received.

你可以让init方法返回这个,然后把调用链接在一起,像这样:

var userB = {
    init: function(nameParam) {
        this.id = MY_GLOBAL.nextId();
        this.name = nameParam;
        return this;
    },
    sayHello: function() {
        console.log('Hello '+ this.name);
    }
};

var bob = Object.create(userB).init('Bob');

新的操作符

用于从构造函数创建对象 新的关键字还执行构造函数

function Car() {
  console.log(this) // this points to myCar
  this.name = "Honda";
}

var myCar = new Car()
console.log(myCar) // Car {name: "Honda", constructor: Object}
console.log(myCar.name) // Honda
console.log(myCar instanceof Car) // true
console.log(myCar.constructor) // function Car() {}
console.log(myCar.constructor === Car) // true
console.log(typeof myCar) // object

Object.create

你也可以使用Object。Create创建一个新对象 但是,它不执行构造函数 对象。Create用于从另一个对象创建一个对象

const Car = {
  name: "Honda"
}

var myCar = Object.create(Car)
console.log(myCar) // Object {}
console.log(myCar.name) // Honda
console.log(myCar instanceof Car) // ERROR
console.log(myCar.constructor) // Anonymous function object
console.log(myCar.constructor === Car) // false
console.log(typeof myCar) // object

对象。create在一些浏览器上还不是标准的,比如IE8, Opera v11.5, Konq 4.3都没有。你可以使用Douglas Crockford的Object版本。为这些浏览器创建,但这不包括在CMS的回答中使用的第二个“初始化对象”参数。

对于跨浏览器代码,同时进行对象初始化的一种方法是自定义Crockford的object .create。这里有一个方法:-

Object.build = function(o) {
   var initArgs = Array.prototype.slice.call(arguments,1)
   function F() {
      if((typeof o.init === 'function') && initArgs.length) {
         o.init.apply(this,initArgs)
      }
   }
   F.prototype = o
   return new F()
}

这维护了Crockford原型继承,也检查对象中的任何init方法,然后用参数运行它,比如说new man('John','Smith')。然后你的代码变成:-

MY_GLOBAL = {i: 1, nextId: function(){return this.i++}}  // For example

var userB = {
    init: function(nameParam) {
        this.id = MY_GLOBAL.nextId();
        this.name = nameParam;
    },
    sayHello: function() {
        console.log('Hello '+ this.name);
    }
};
var bob = Object.build(userB, 'Bob');  // Different from your code
bob.sayHello();

所以bob继承了sayHello方法,现在拥有自己的属性id=1和name=' bob '。当然,这些属性既可写又可枚举。这也是一种比ECMA Object简单得多的初始化方法。创建,特别是当您不关心可写、可枚举和可配置属性时。

对于没有init方法的初始化,可以使用以下Crockford mod

Object.gen = function(o) {
   var makeArgs = arguments 
   function F() {
      var prop, i=1, arg, val
      for(prop in o) {
         if(!o.hasOwnProperty(prop)) continue
         val = o[prop]
         arg = makeArgs[i++]
         if(typeof arg === 'undefined') break
         this[prop] = arg
      }
   }
   F.prototype = o
   return new F()
}

这将使用Object填充userB自己的属性,按照它们定义的顺序。在userB参数之后从左到右生成参数。它使用for(prop in o)循环,因此,根据ECMA标准,属性枚举的顺序不能保证与属性定义的顺序相同。然而,在(4)主要浏览器上测试的几个代码示例显示,如果使用hasOwnProperty过滤器,它们是相同的,有时甚至不使用。

MY_GLOBAL = {i: 1, nextId: function(){return this.i++}};  // For example

var userB = {
   name: null,
   id: null,
   sayHello: function() {
      console.log('Hello '+ this.name);
   }
}

var bob = Object.gen(userB, 'Bob', MY_GLOBAL.nextId());

我想说的是比Object简单一些。因为userB不需要init方法。此外,userB并不是特定的构造函数,但看起来像一个普通的单例对象。因此,使用这个方法,你可以从普通的普通对象构造和初始化。

我更喜欢结束的方法。

我还在用new。 我不用object。create。 我不用这个。

我仍然使用new,因为我喜欢它的声明性。

考虑简单的继承。

window.Quad = (function() {

    function Quad() {

        const wheels = 4;
        const drivingWheels = 2;

        let motorSize = 0;

        function setMotorSize(_) {
            motorSize = _;
        }

        function getMotorSize() {
            return motorSize;
        }

        function getWheelCount() {
            return wheels;
        }

        function getDrivingWheelCount() {
            return drivingWheels;
        }
        return Object.freeze({
            getWheelCount,
            getDrivingWheelCount,
            getMotorSize,
            setMotorSize
        });
    }

    return Object.freeze(Quad);
})();

window.Car4wd = (function() {

    function Car4wd() {
        const quad = new Quad();

        const spareWheels = 1;
        const extraDrivingWheels = 2;

        function getSpareWheelCount() {
            return spareWheels;
        }

        function getDrivingWheelCount() {
            return quad.getDrivingWheelCount() + extraDrivingWheels;
        }

        return Object.freeze(Object.assign({}, quad, {
            getSpareWheelCount,
            getDrivingWheelCount
        }));
    }

    return Object.freeze(Car4wd);
})();

let myQuad = new Quad();
let myCar = new Car4wd();
console.log(myQuad.getWheelCount()); // 4
console.log(myQuad.getDrivingWheelCount()); // 2
console.log(myCar.getWheelCount()); // 4
console.log(myCar.getDrivingWheelCount()); // 4 - The overridden method is called
console.log(myCar.getSpareWheelCount()); // 1

反馈鼓励。