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”?


当前回答

Object的另一种可能用法。Create是用一种廉价而有效的方式克隆不可变对象。

var anObj = {
    a: "test",
    b: "jest"
};

var bObj = Object.create(anObj);

bObj.b = "gone"; // replace an existing (by masking prototype)
bObj.c = "brand"; // add a new to demonstrate it is actually a new obj

// now bObj is {a: test, b: gone, c: brand}

Notes: The above snippet creates a clone of an source object (aka not a reference, as in cObj = aObj). It benefits over the copy-properties method (see 1), in that it does not copy object member properties. Rather it creates another -destination- object with it's prototype set on the source object. Moreover when properties are modified on the dest object, they are created "on the fly", masking the prototype's (src's) properties.This constitutes a fast an effective way of cloning immutable objects.

这里需要注意的是,这适用于创建后不应该修改的源对象(不可变)。如果源对象在创建后被修改,克隆的所有未屏蔽属性也将被修改。

这里(http://jsfiddle.net/y5b5q/1/)(需要对象。创建功能强大的浏览器)。

其他回答

新的操作符

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

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

你可以让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');

由于只有一个继承级别,您的示例可能不会让您看到Object.create的真正好处。

该方法允许您轻松实现差异继承,其中对象可以直接从其他对象继承。

在你的userB的例子中,我不认为你的init方法应该是公共的,甚至不存在,如果你在一个现有的对象实例上再次调用这个方法,id和name属性将会改变。

对象。Create允许你使用它的第二个参数初始化对象属性,例如:

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

var bob = Object.create(userB, {
  'id' : {
    value: MY_GLOBAL.nextId(),
    enumerable:true // writable:false, configurable(deletable):false by default
  },
  'name': {
    value: 'Bob',
    enumerable: true
  }
});

如您所见,属性可以在Object的第二个参数上初始化。使用类似于object . defineproperties和object . defineproperty方法使用的语法创建一个对象文字。

它允许您设置属性属性(可枚举、可写或可配置),这非常有用。

你必须创建一个自定义的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');

虽然Douglas Crockford曾经是Object.create()的狂热拥护者,而且基本上是他导致了这个构造实际上是在javascript中,但他不再有这种观点了。

他不再使用Object。创造,因为他完全停止使用这个关键字,因为它会带来太多麻烦。例如,如果不小心,它很容易指向全局对象,这可能会产生非常糟糕的后果。他声称不使用这个物体。创造已经没有意义了。

你可以看看2014年他在Nordic.js演讲的视频:

https://www.youtube.com/watch?v=PSGEjv3Tqo0