我们可以在 javascript 中将通用对象转换为自定义对象类型吗?
Posted
技术标签:
【中文标题】我们可以在 javascript 中将通用对象转换为自定义对象类型吗?【英文标题】:Can we cast a generic object to a custom object type in javascript? 【发布时间】:2012-02-02 22:42:06 【问题描述】:例如,我在代码的某处已经有了这个对象,它是一个通用对象:
var person1=lastName:"Freeman",firstName:"Gordon";
我有一个 Person 对象的构造函数:
function Person()
this.getFullName=function()
return this.lastName + ' ' + this.firstName;
是否有一种简单的语法可以让我们将 person1 转换为 Person 类型的对象?
【问题讨论】:
javascript 中没有强制转换,所以...简短的回答是否定的。更长的答案是......仍然没有。这是因为 [[prototype]] 只能在创建对象时设置。但是,人们可以对从 Person 到 person1 的方法/属性进行猴子修补(复制),无论如何,这是一些“类框架”使用的一种方法。我可能会在“复制构造函数”中从 person1 创建一个 new Person。 【参考方案1】:@PeterOlson 的答案可能会在当天恢复,但看起来
Object.create
已更改。 我会像 @user166390 在 cmets 中所说的那样采用复制构造方法。 我死灵这篇文章的原因是因为我需要这样的实现。
现在我们可以使用Object.assign
(感谢@SayanPal 解决方案)和 ES6 语法:
class Person
constructor(obj)
obj && Object.assign(this, obj);
getFullName()
return `$this.lastName $this.firstName`;
用法:
const newPerson = new Person(person1)
newPerson.getFullName() // -> Freeman Gordon
下面的 ES5 答案
function Person(obj)
for(var prop in obj)
// for safety you can use the hasOwnProperty function
this[prop] = obj[prop];
用法:
var newPerson = new Person(person1);
console.log(newPerson.getFullName()); // -> Freeman Gordon
使用较短的版本,1.5 班轮:
function Person()
if(arguments[0]) for(var prop in arguments[0]) this[prop] = arguments[0][prop];
jsfiddle
【讨论】:
“1.5 liner”版本的道具,喜欢。 但是这个答案实际上只是编写了大多数框架在其中的extend
函数......而Object.assign
是该函数的替代品......截至今天。只有 Internet Explorer 和 Safari Object.assign polyfill 并在真正的 Object.assign 不存在时使用它。在我的项目中,我有一段代码可以检查所需的功能,如果缺少任何功能,则为这些功能加载带有 polyfill 的第二个脚本。
@StijndeWitt 我必须同意在此解决方案上使用Object.assign
。请参阅使用 assign 方法的@SayanPal 解决方案。我会在某个时候更新这个答案;)
@StijndeWitt 是时候更新我的答案了!我看到了Object.assign
的力量【参考方案2】:
没有。
但是,如果您希望将 person1
对象视为 Person
,您可以使用 call
在 person1
上调用 Person
原型上的方法:
Person.prototype.getFullNamePublic = function()
return this.lastName + ' ' + this.firstName;
Person.prototype.getFullNamePublic.call(person1);
虽然这显然不适用于在 Person 构造函数中创建的特权方法,例如您的 getFullName
方法。
【讨论】:
【参考方案3】:这并不完全是一个答案,而是分享我的发现,并希望得到一些支持/反对它的批判性论据,因为具体来说我不知道它的效率如何。
我最近需要为我的项目执行此操作。我使用Object.assign
完成此操作,更准确地说,它是这样完成的:Object.assign(new Person(...), anObjectLikePerson)
。
这里是我的JSFiddle的链接,也是代码的主要部分:
function Person(firstName, lastName)
this.firstName = firstName;
this.lastName = lastName;
this.getFullName = function()
return this.lastName + ' ' + this.firstName;
var persons = [
lastName: "Freeman",
firstName: "Gordon"
,
lastName: "Smith",
firstName: "John"
];
var stronglyTypedPersons = [];
for (var i = 0; i < persons.length; i++)
stronglyTypedPersons.push(Object.assign(new Person("", ""), persons[i]));
【讨论】:
这种语法非常好用且高效。大概也是要走的路吧。 Too bad some browsers don't support it yet. @A1rPun pollyfill 可用于这些情况:kangax.github.io/compat-table/es6/… 这是最好的答案。 assign() 和 create() 的区别在于 1) assign 使用非对象属性; 2) 分配忽略未知属性。【参考方案4】:这借用了这里的其他一些答案,但我认为它可能会对某人有所帮助。如果您在自定义对象上定义以下函数,那么您就有了一个工厂函数,您可以将一个通用对象传递给该函数,它会为您返回一个类的实例。
CustomObject.create = function (obj)
var field = new CustomObject();
for (var prop in obj)
if (field.hasOwnProperty(prop))
field[prop] = obj[prop];
return field;
这样使用
var typedObj = CustomObject.create(genericObj);
【讨论】:
我使用了一个从标准类扩展而来的自定义类。现在,当全局侦听器的回调完成时,它会返回一个标准的分类对象作为参数。我所做的是我尝试了所有符合我需求的答案。 IE。将“标准”对象嵌入到我设计的对象中。 .最后这个答案有帮助!【参考方案5】:这只是简短的 ES5 风格的 Sayan Pal 回答的总结:
var Foo = function()
this.bar = undefined;
this.buzz = undefined;
var foo = Object.assign(new Foo(),
bar: "whatever",
buzz: "something else"
);
我喜欢它,因为它最接近 .Net 中非常简洁的对象初始化:
var foo = new Foo()
bar: "whatever",
...
【讨论】:
【参考方案6】:这对我有用。对于简单的对象来说很简单。
class Person
constructor(firstName, lastName)
this.firstName = firstName;
this.lastName = lastName;
getFullName()
return this.lastName + " " + this.firstName;
static class(obj)
return new Person(obj.firstName, obj.lastName);
var person1 =
lastName: "Freeman",
firstName: "Gordon"
;
var gordon = Person.class(person1);
console.log(gordon.getFullName());
我也在寻找一个简单的解决方案,这就是我根据所有其他答案和我的研究得出的结论。基本上,Person 类有另一个构造函数,称为“类”,它使用与 Person 相同“格式”的通用对象。 我希望这也能对某人有所帮助。
【讨论】:
明智,避免使用保留字class
作为转换方法的名称!我建议改用Person.fromObject(obj)
之类的东西。【参考方案7】:
如果你愿意,这里有办法。 1st 用你所有想要的属性制作一个对象。 然后使用您的自定义值调用此对象。 这是JSFiddle的链接,也是
的主要部分 function Message(obj)
this.key = Date.now();
this.text = "";
this.type = "client";
this.status = 0;
this.senderID = "";
this.name = "";
this.photoURL = "";
this.metaData = [];
this.time = new Date().toISOString();
for (var prop in obj)
if (this.hasOwnProperty(prop))
this[prop] = obj[prop];
else
this.metaData = [ ...this.metaData, [prop]: obj[prop] ];
const getAllMessages = function (messages=[])
var newMessages = [];
for (var i = 0; i < messages.length; i++)
newMessages.push(new Message(messages[i]));
return newMessages;
;
var messages = [
name: "Jhon",
text: "Hello 1"
,
name: "Smith",
text: "Hello 2",
meta1: "meta data 1"
];
console.log("single Instances", new Message(messages[0]));
console.log("Multiple Instances",getAllMessages(messages));
【讨论】:
以上是关于我们可以在 javascript 中将通用对象转换为自定义对象类型吗?的主要内容,如果未能解决你的问题,请参考以下文章
在 JavaScript 中将 JSON 对象转换为 CSV 格式