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创建对象,但仍然可以调用create方法。

例如:如果你想定义一个自定义元素,它必须派生自HTMLElement。

proto = new HTMLElement  //fail :(
proto = Object.create( HTMLElement.prototype )  //OK :)
document.registerElement( "custom-element", { prototype: proto } )

其他回答

你必须创建一个自定义的Object.create()函数。它解决了Crockfords的问题,也调用了init函数。

这是可行的:

var userBPrototype = {
    init: function(nameParam) {
        this.name = nameParam;
    },
    sayHello: function() {
        console.log('Hello '+ this.name);
    }
};


function UserB(name) {
    function F() {};
    F.prototype = userBPrototype;
    var f = new F;
    f.init(name);
    return f;
}

var bob = UserB('bob');
bob.sayHello();

这里UserB类似于Object。创造,但要适应我们的需要。

如果你愿意,也可以拨打:

var bob = new UserB('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

反馈鼓励。

它的优点是。在大多数浏览器中,Create通常比new慢

在这个jsperf示例中,在Chromium浏览器中,browser new的速度是Object.create(obj)的30倍,尽管两者都非常快。这很奇怪,因为new要做更多的事情(比如调用构造函数),而Object。create应该只是创建一个新的对象,并将传入的对象作为原型(crockford语言中的秘密链接)

也许浏览器在创建Object时还没有跟上进度。创造更有效的方法(也许他们是基于新的方法……甚至在本地代码中)

有时不能使用NEW创建对象,但仍然可以调用create方法。

例如:如果你想定义一个自定义元素,它必须派生自HTMLElement。

proto = new HTMLElement  //fail :(
proto = Object.create( HTMLElement.prototype )  //OK :)
document.registerElement( "custom-element", { prototype: proto } )

我认为问题的重点是理解new和Object之间的区别。创建方法。根据这个答案和这个视频,new关键字做了下面的事情:

创建新对象。 将新对象链接到构造函数(原型)。 使此变量指向新对象。 使用new对象执行构造函数,隐式执行返回this; 将构造函数函数名赋给新对象的属性构造函数。

对象。Create只执行第1和第2步!

在代码示例中提供的问题,这不是什么大问题,但在下一个例子中,它是:

var onlineUsers = [];
function SiteMember(name) {
    this.name = name;
    onlineUsers.push(name);
}
SiteMember.prototype.getName = function() {
    return this.name;
}
function Guest(name) {
    SiteMember.call(this, name);
}
Guest.prototype = new SiteMember();

var g = new Guest('James');
console.log(onlineUsers);

作为副作用的结果将是:

[ undefined, 'James' ]

因为盖斯特。prototype = new SiteMember(); 但是我们不需要执行父构造函数方法,我们只需要使方法getName在Guest中可用。 因此我们必须使用Object.create。 如果替换Guest。prototype = new SiteMember(); 来的客人。prototype = Object.create(sitember .prototype);结果是:

[ 'James' ]