用JavaScript创建对象非常容易: 一对花括号就可以完成任务,但这既不是创建对象的唯一方法,也不是您需要使用的唯一方法 。
当编程语言是关于对象的时 ,我们需要学习的第一件事就是如何创建对象 。
如果要在页面上显示当前日期,则需要一个Date
的运行时实例,该实例携带有关当前日期的信息。
例如, Date
是一个内置对象,可为我们提供有关日期的信息。
在JavaScript中,对象实例是从内置对象创建的,并且在程序运行时就存在。
对象实例的创建称为实例化 。
在JavaScript中, 一切都是对象 ,每个对象都有一个称为Object
的最终祖先 。
JavaScript还允许我们定义自己的对象 ,这些对象可以在运行时生成自己的对象实例。
1.
创建新对象实例的最常见,最著名的方法之一是使用new
运算符 。
其基本语法如下所示:
构造函数是对象的一种方法,它将该对象的新实例放在一起。
您需要一个构造函数来使new
运算符起作用。
new constructor()
构造函数与其所属的对象具有相同的名称 。
构造函数可以接受可用于为其构造的对象实例更改或添加属性的参数 。
这是一个如何使用new
关键字创建Date()
对象的实例的示例:
dt = new Date(2017, 0 , 1)
console.log(dt)
// Sun Jan 01 2017 00:00:00 GMT+0100
对象的不同构造函数采用不同的参数来创建具有不同属性的同类对象实例。
Date()
是用于创建新Date
对象的构造函数。
有些对象没有构造函数 : Math
, JSON
和Reflect
,但是它们仍然是普通对象。
并非可以像Date
那样实例化JavaScript中的所有内置对象。
它只能作为返回新Symbol
值的函数来调用 。
在已经构造(S)内置对象, Symbol
不能在构造风格称为实例化一个新的Symbol
实例。
Function
, Array
, Error
和RegExp
也可以作为函数调用 ,而无需使用new
关键字,它们将实例化并返回一个新的对象实例。
此外,在具有构造函数的内置对象中,并非所有人都需要使用new
运算符调用其构造函数才能实例化。
2.
反射是编程语言的功能,可以在运行时 检查和更新一些基本实体 ,例如对象和类。
后端程序员可能已经熟悉反射API 。
但是,JavaScript中也终于出现了合适的反射API 。
在JavaScript中,您已经可以使用Object
执行一些反射操作。
Reflect
对象没有构造函数 ,因此无法使用new
运算符实例化,并且就像Math
和JSON
, 也不能将其称为函数 。
Reflect
对象具有一组用于创建和更新对象实例的方法 。
但是, Reflect
与new
运算符等效 : Reflect.construct()
方法。
Reflect.construct(target, argumentsList[, newTarget])
var dt = Reflect.construct(Date, [2017, 0 , 1]);
console.log(dt);
// Sun Jan 01 2017 00:00:00 GMT+0100
它还允许您使用newTarget
参数 ,这是与new
运算符相比的另一个优点。
尽管您仍然可以使用new
,但是Reflection是ECMAScript 6标准 。
上面的代码与使用new
运算符实例化Date()
具有相同的效果 。
简而言之,对象从其原型获取其成员。
原型是对象的属性,该对象的值也是一个对象 ,带有原始对象的属性。
在这里,让我们看一个例子:
class A {
constructor() {
this.message = function() {
console.log('message from A')
}
}
}
class B {
constructor() {
}
message() {
console.log('message from B')
}
data() {
console.log('data from B')
}
}
obj = Reflect.construct(A, [], B)
console.log(obj.message());
// message from A
console.log(obj.data());
// data from B
console.log(obj instanceof B)
// true
通过使B
作为第三个参数,以Reflect.construct()
所述的原型值obj
对象被制成相同的原型B
的构造(其具有的属性message
和data
)。
但是,由于obj
是使用A
制成A
,因此它还具有从A
接收到的自己的message
。
因此, obj
可以访问其原型中可用的message
和data
。
即使obj
构造为数组,它也不是Array
的实例 ,因为其原型已设置为Object
。
obj = Reflect.construct(Array, [1,2,3], Object)
console.log(obj)
// Array [ 1, 2, 3 ]
console.log(obj instanceof Array)
// false
当您要使用多个蓝图创建一个对象时, Reflect.construct()
会很有用 。
3.
这似乎也与使用new
运算符非常相似,但事实并非如此。
您还可以通过Object.create()
创建具有特定原型的新普通对象 。
Object.create(O[, propertiesObject])
可选的propertiesObject
参数是您可能想要添加到新对象的属性列表 。
O
参数是为将要创建的新对象提供原型的对象。
class A {
constructor() {
}
message() {
console.log('message from A')
}
}
var obj = Object.create(new A(), {
data: {
writable: true,
configurable: true,
value: function(){return 'data from obj'}
}
})
console.log(obj.message())
// message from A
console.log(obj.data())
// data from obj
obj1 = Object.create(new A(), {
foo: {
writable: true,
configurable: true,
value: function(){return 'foo from obj1'}
}
})
console.log(obj1.message())
// message from A
console.log(obj1.foo())
// foo from obj1
因此,如您所见,我们可以将属性和方法添加到新对象中 。
在obj
对象中,添加的属性是data
,而在obj1
,添加的属性是foo
。
Object.create()
语法省去了分别编码所有代码的麻烦。
当您要创建多个相同类型但具有不同补充属性或方法的 对象时,这非常有用 。
翻译自: https://www.hongkiat.com/blog/object-oriented-javascript/