“new Object()”和对象字面量表示法有什么区别?

发布于 2024-10-10 01:11:39 字数 228 浏览 5 评论 0原文

用于创建对象的基于构造函数的语法之间有什么区别:

person = new Object()

... 和文字语法:

person = {
    property1 : "Hello"
};

看起来两者都执行相同的操作,尽管 JSLint 更喜欢使用对象文字表示法。

哪一个更好,为什么?

What is the difference between this constructor-based syntax for creating an object:

person = new Object()

...and this literal syntax:

person = {
    property1 : "Hello"
};

It appears that both do the same thing, although JSLint prefers you use object literal notation.

Which one is better and why?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(13

黒涩兲箜 2024-10-17 01:11:39

对于您的示例中没有方法的简单对象来说没有什么区别。
但是,当您开始向对象添加方法时,就会出现很大的差异。

字面方式:

function Obj( prop ) { 
    return { 
        p : prop, 
        sayHello : function(){ alert(this.p); }, 
    }; 
} 

原型方式:

function Obj( prop ) { 
    this.p = prop; 
} 
Obj.prototype.sayHello = function(){alert(this.p);}; 

两种方式都允许创建 Obj 实例,如下所示:

var foo = new Obj( "hello" ); 

但是,使用字面方式,您可以在每个实例中携带 sayHello 方法的副本你的对象。而使用原型方式时,方法在对象原型中定义并在所有对象实例之间共享。
如果你有很多对象或者很多方法,直接的方式可能会导致相当大的内存浪费。

There is no difference for a simple object without methods as in your example.
However, there is a big difference when you start adding methods to your object.

Literal way:

function Obj( prop ) { 
    return { 
        p : prop, 
        sayHello : function(){ alert(this.p); }, 
    }; 
} 

Prototype way:

function Obj( prop ) { 
    this.p = prop; 
} 
Obj.prototype.sayHello = function(){alert(this.p);}; 

Both ways allow creation of instances of Obj like this:

var foo = new Obj( "hello" ); 

However, with the literal way, you carry a copy of the sayHello method within each instance of your objects. Whereas, with the prototype way, the method is defined in the object prototype and shared between all object instances.
If you have a lot of objects or a lot of methods, the literal way can lead to quite big memory waste.

不美如何 2024-10-17 01:11:39

他们都做同样的事情(除非有人做了不寻常的事情),除了你的第二个创建一个对象并为其添加一个属性之外。但文字符号在源代码中占用的空间更少。可以清楚地识别正在发生的事情,因此使用 new Object(),您实际上只是输入更多内容并且(理论上,如果没有被 JavaScript 引擎优化的话)执行不必要的函数调用。

从技术上讲,这些

person = new Object() /*You should put a semicolon here too.  
It's not required, but it is good practice.*/ 
-or-

person = {
    property1 : "Hello"
};

并没有做同样的事情。第一个只是创建一个对象。第二个创建一个并分配一个属性。为了使第一个相同,您需要第二步来创建和分配属性。

有人可以做的“不寻常的事情”是隐藏或分配给默认的全局对象:

// Don't do this
Object = 23;

在这种非常不寻常的情况下,新对象> 将失败,但 {} 可以工作。

实际上,没有理由使用 new Object 而不是 {}(除非您做过那件非常不寻常的事情)。

They both do the same thing (unless someone's done something unusual), other than that your second one creates an object and adds a property to it. But literal notation takes less space in the source code. It's clearly recognizable as to what is happening, so using new Object(), you are really just typing more and (in theory, if not optimized out by the JavaScript engine) doing an unnecessary function call.

These

person = new Object() /*You should put a semicolon here too.  
It's not required, but it is good practice.*/ 
-or-

person = {
    property1 : "Hello"
};

technically do not do the same thing. The first just creates an object. The second creates one and assigns a property. For the first one to be the same you then need a second step to create and assign the property.

The "something unusual" that someone could do would be to shadow or assign to the default Object global:

// Don't do this
Object = 23;

In that highly-unusual case, new Object will fail but {} will work.

In practice, there's never a reason to use new Object rather than {} (unless you've done that very unusual thing).

凉薄对峙 2024-10-17 01:11:39

在 JavaScript 中,我们可以通过两种方式声明一个新的空对象:

var obj1 = new Object();  
var obj2 = {};  

我没有发现任何迹象表明这两者在幕后操作方式上有任何显着差异(如果我错了,请纠正我 - 我很乐意知道)。然而,第二种方法(使用对象文字表示法)提供了一些优点。

  1. 它更短(准确地说是 10 个字符)
  2. 更容易、更结构化地动态创建对象
  3. 即使某些小丑无意中覆盖了 Object 也没关系

考虑一个包含成员 Name 和 TelNo 的新对象。使用 new Object() 约定,我们可以像这样创建它:

var obj1 = new Object();  
obj1.Name = "A Person";  
obj1.TelNo = "12345"; 

Expando Properties JavaScript 功能允许我们以这种方式动态创建新成员,并且我们实现了预期目的。然而,这种方式不是很结构化或封装。如果我们想在创建时指定成员,而不必依赖扩展属性和创建后赋值,该怎么办?

这就是对象文字表示法可以提供帮助的地方:

var obj1 = {Name:"A Person",TelNo="12345"};  

在这里,我们用一行代码实现了相同的效果,并且字符数量明显减少。

对上述对象构造方法的进一步讨论可以在以下位置找到:JavaScript 和面向对象编程 (OOP)。

最后,那个覆盖 Object 的白痴怎么样了?你以为这不可能吗?好吧,这个 JSFiddle 证明了事实并非如此。使用对象字面量表示法可以防止我们陷入这种滑稽的行为。

(来自 http:// /www.jameswiseman.com/blog/2011/01/19/jslint-messages-use-the-object-literal-notation/

In JavaScript, we can declare a new empty object in two ways:

var obj1 = new Object();  
var obj2 = {};  

I have found nothing to suggest that there is any significant difference these two with regard to how they operate behind the scenes (please correct me if i am wrong – I would love to know). However, the second method (using the object literal notation) offers a few advantages.

  1. It is shorter (10 characters to be precise)
  2. It is easier, and more structured to create objects on the fly
  3. It doesn’t matter if some buffoon has inadvertently overridden Object

Consider a new object that contains the members Name and TelNo. Using the new Object() convention, we can create it like this:

var obj1 = new Object();  
obj1.Name = "A Person";  
obj1.TelNo = "12345"; 

The Expando Properties feature of JavaScript allows us to create new members this way on the fly, and we achieve what were intending. However, this way isn’t very structured or encapsulated. What if we wanted to specify the members upon creation, without having to rely on expando properties and assignment post-creation?

This is where the object literal notation can help:

var obj1 = {Name:"A Person",TelNo="12345"};  

Here we have achieved the same effect in one line of code and significantly fewer characters.

A further discussion the object construction methods above can be found at: JavaScript and Object Oriented Programming (OOP).

And finally, what of the idiot who overrode Object? Did you think it wasn’t possible? Well, this JSFiddle proves otherwise. Using the object literal notation prevents us from falling foul of this buffoonery.

(From http://www.jameswiseman.com/blog/2011/01/19/jslint-messages-use-the-object-literal-notation/)

巨坚强 2024-10-17 01:11:39

在使用 Node.js 的计算机上,我运行了以下命令:

console.log('Testing Array:');
console.time('using[]');
for(var i=0; i<200000000; i++){var arr = []};
console.timeEnd('using[]');

console.time('using new');
for(var i=0; i<200000000; i++){var arr = new Array};
console.timeEnd('using new');

console.log('Testing Object:');

console.time('using{}');
for(var i=0; i<200000000; i++){var obj = {}};
console.timeEnd('using{}');

console.time('using new');
for(var i=0; i<200000000; i++){var obj = new Object};
console.timeEnd('using new');

注意,这是此处找到的内容的扩展: 为什么 arr = [] 比 arr = new Array 更快?

我的输出如下:

Testing Array:
using[]: 1091ms
using new: 2286ms
Testing Object:
using{}: 870ms
using new: 5637ms

显然 {} 和 [] 比使用 new 创建空对象/数组更快。

On my machine using Node.js, I ran the following:

console.log('Testing Array:');
console.time('using[]');
for(var i=0; i<200000000; i++){var arr = []};
console.timeEnd('using[]');

console.time('using new');
for(var i=0; i<200000000; i++){var arr = new Array};
console.timeEnd('using new');

console.log('Testing Object:');

console.time('using{}');
for(var i=0; i<200000000; i++){var obj = {}};
console.timeEnd('using{}');

console.time('using new');
for(var i=0; i<200000000; i++){var obj = new Object};
console.timeEnd('using new');

Note, this is an extension of what is found here: Why is arr = [] faster than arr = new Array?

my output was the following:

Testing Array:
using[]: 1091ms
using new: 2286ms
Testing Object:
using{}: 870ms
using new: 5637ms

so clearly {} and [] are faster than using new for creating empty objects/arrays.

夏の忆 2024-10-17 01:11:39

这里的每个人都在谈论两者的相似之处。我会指出其中的差异。

  1. 使用new Object()允许您传递另一个对象。明显的结果是新创建的对象将被设置为相同的引用。这是示例代码:

    var obj1 = new Object();
    obj1.a = 1;
    var obj2 = 新对象(obj1);
    obj2.a // 1
    
  2. 其用法并不限于 OOP 对象中的对象。其他类型也可以传递给它。该函数将相应地设置类型。例如,如果我们将整数 1 传递给它,则会为我们创建一个 number 类型的对象。

    var obj = new Object(1);
    typeof obj //“数字”
    
  3. 如果向使用上述方法(new Object(1))创建的对象添加属性,则该对象将转换为对象类型。

    var obj = new Object(1);
    typeof obj //“数字”
    obj.a = 2;
    typeof obj //“对象”
    
  4. 如果对象是对象子类的副本,我们可以添加属性而不进行类型转换。

    var obj = new Object("foo");
    typeof obj //“对象”
    obj === "foo" // true
    obj.a = 1;
    obj === "foo" // true
    obj.a // 1
    var str = “foo”;
    str.a = 1;
    str.a // 未定义
    

Everyone here is talking about the similarities of the two. I am gonna point out the differences.

  1. Using new Object() allows you to pass another object. The obvious outcome is that the newly created object will be set to the same reference. Here is a sample code:

    var obj1 = new Object();
    obj1.a = 1;
    var obj2 = new Object(obj1);
    obj2.a // 1
    
  2. The usage is not limited to objects as in OOP objects. Other types could be passed to it too. The function will set the type accordingly. For example if we pass integer 1 to it, an object of type number will be created for us.

    var obj = new Object(1);
    typeof obj // "number"
    
  3. The object created using the above method (new Object(1)) would be converted to object type if a property is added to it.

    var obj = new Object(1);
    typeof obj // "number"
    obj.a = 2;
    typeof obj // "object"
    
  4. If the object is a copy of a child class of object, we could add the property without the type conversion.

    var obj = new Object("foo");
    typeof obj // "object"
    obj === "foo" // true
    obj.a = 1;
    obj === "foo" // true
    obj.a // 1
    var str = "foo";
    str.a = 1;
    str.a // undefined
    
深陷 2024-10-17 01:11:39

实际上,在 JavaScript 中创建对象的方法有多种。当您只想创建一个对象时,使用“new”运算符创建“基于构造函数的”对象没有任何好处。它与使用“对象文字”语法创建对象相同。但是,当您考虑“原型继承”时,使用“new”运算符创建的“基于构造函数的”对象会发挥令人难以置信的作用。您无法使用使用文字语法创建的对象来维护继承链。但是您可以创建一个构造函数,将属性和方法附加到其原型。然后,如果您使用“new”运算符将此构造函数分配给任何变量,它将返回一个对象,该对象将有权访问该构造函数原型所附加的所有方法和属性。

下面是使用构造函数创建对象的示例(请参阅底部的代码说明):

function Person(firstname, lastname) {
    this.firstname = firstname;
    this.lastname = lastname;
}

Person.prototype.fullname = function() {
    console.log(this.firstname + ' ' + this.lastname);
}

var zubaer = new Person('Zubaer', 'Ahammed');
var john = new Person('John', 'Doe');

zubaer.fullname();
john.fullname();

现在,您可以通过实例化 Person 构造函数来创建任意多个对象,并且所有对象都将从它继承 fullname() 。

笔记:
this”关键字将引用构造函数中的空对象,每当您使用“new”运算符从 Person 创建新对象时,它都会自动返回一个包含所有内容的对象附加“this”关键字的属性和方法。这些对象肯定会继承 Person 构造函数的 prototype 所附加的方法和属性(这是这种方法的主要优点)。

顺便说一句,如果您想使用“对象文字”语法获得相同的功能,则必须在所有对象上创建 fullname() ,如下所示:

var zubaer = {
    firstname: 'Zubaer',
    lastname: 'Ahammed',
    fullname: function() {
        console.log(this.firstname + ' ' + this.lastname);
    }
};

var john= {
    firstname: 'John',
    lastname: 'Doe',
    fullname: function() {
        console.log(this.firstname + ' ' + this.lastname);
    }
};

zubaer.fullname();
john.fullname();

最后,如果您现在问为什么我应该使用构造函数方法而不是对象文字方法:

*** 原型继承允许简单的继承链,这非常有用和强大。

*** 它通过继承构造函数原型中定义的常用方法和属性来节省内存。否则,您将不得不在所有对象中一遍又一遍地复制它们。

我希望这是有道理的。

Actually, there are several ways to create objects in JavaScript. When you just want to create an object there's no benefit of creating "constructor-based" objects using "new" operator. It's same as creating an object using "object literal" syntax. But "constructor-based" objects created with "new" operator comes to incredible use when you are thinking about "prototypal inheritance". You cannot maintain inheritance chain with objects created with literal syntax. But you can create a constructor function, attach properties and methods to its prototype. Then if you assign this constructor function to any variable using "new" operator, it will return an object which will have access to all of the methods and properties attached with the prototype of that constructor function.

Here is an example of creating an object using constructor function (see code explanation at the bottom):

function Person(firstname, lastname) {
    this.firstname = firstname;
    this.lastname = lastname;
}

Person.prototype.fullname = function() {
    console.log(this.firstname + ' ' + this.lastname);
}

var zubaer = new Person('Zubaer', 'Ahammed');
var john = new Person('John', 'Doe');

zubaer.fullname();
john.fullname();

Now, you can create as many objects as you want by instantiating Person construction function and all of them will inherit fullname() from it.

Note:
"this" keyword will refer to an empty object within a constructor function and whenever you create a new object from Person using "new" operator it will automatically return an object containing all of the properties and methods attached with the "this" keyword. And these object will for sure inherit the methods and properties attached with the prototype of the Person constructor function (which is the main advantage of this approach).

By the way, if you wanted to obtain the same functionality with "object literal" syntax, you would have to create fullname() on all of the objects like below:

var zubaer = {
    firstname: 'Zubaer',
    lastname: 'Ahammed',
    fullname: function() {
        console.log(this.firstname + ' ' + this.lastname);
    }
};

var john= {
    firstname: 'John',
    lastname: 'Doe',
    fullname: function() {
        console.log(this.firstname + ' ' + this.lastname);
    }
};

zubaer.fullname();
john.fullname();

At last, if you now ask why should I use constructor function approach instead of object literal approach:

*** Prototypal inheritance allows a simple chain of inheritance which can be immensely useful and powerful.

*** It saves memory by inheriting common methods and properties defined in constructor functions prototype. Otherwise, you would have to copy them over and over again in all of the objects.

I hope this makes sense.

野味少女 2024-10-17 01:11:39

另外,根据一些 O'Really javascript 书籍......(引用)

使用文字而不是对象构造函数的另一个原因是没有范围解析。因为您可能创建了一个同名的本地构造函数,所以解释器需要从您调用 Object() 的位置一直查找作用域链,直到找到全局 Object 构造函数。

Also, according to some of the O'Really javascript books....(quoted)

Another reason for using literals as opposed to the Object constructor is that there is no scope resolution. Because it’s possible that you have created a local constructor with the same name, the interpreter needs to look up the scope chain from the place you are calling Object() all the way up until it finds the global Object constructor.

北渚 2024-10-17 01:11:39

2019 更新

我在 OSX High Sierra 10.13.6 节点版本 10.13.0 上运行了与 @rjloura 相同的代码,这些是结果

console.log('Testing Array:');
console.time('using[]');
for(var i=0; i<200000000; i++){var arr = []};
console.timeEnd('using[]');

console.time('using new');
for(var i=0; i<200000000; i++){var arr = new Array};
console.timeEnd('using new');

console.log('Testing Object:');

console.time('using{}');
for(var i=0; i<200000000; i++){var obj = {}};
console.timeEnd('using{}');

console.time('using new');
for(var i=0; i<200000000; i++){var obj = new Object};
console.timeEnd('using new');


Testing Array:
using[]: 117.613ms
using new: 117.168ms
Testing Object:
using{}: 117.205ms
using new: 118.644ms

2019 Update

I ran the same code as @rjloura on my OSX High Sierra 10.13.6 node version 10.13.0 and these are the results

console.log('Testing Array:');
console.time('using[]');
for(var i=0; i<200000000; i++){var arr = []};
console.timeEnd('using[]');

console.time('using new');
for(var i=0; i<200000000; i++){var arr = new Array};
console.timeEnd('using new');

console.log('Testing Object:');

console.time('using{}');
for(var i=0; i<200000000; i++){var obj = {}};
console.timeEnd('using{}');

console.time('using new');
for(var i=0; i<200000000; i++){var obj = new Object};
console.timeEnd('using new');


Testing Array:
using[]: 117.613ms
using new: 117.168ms
Testing Object:
using{}: 117.205ms
using new: 118.644ms
冰火雁神 2024-10-17 01:11:39

我发现了 ES6/ES2015 的一个区别。不能使用简写箭头函数语法返回对象,除非用 new Object() 包围该对象。

> [1, 2, 3].map(v => {n: v});
[ undefined, undefined, undefined ]
> [1, 2, 3].map(v => new Object({n: v}));
[ { n: 1 }, { n: 2 }, { n: 3 } ]

这是因为编译器对 {} 括号感到困惑,并认为 n: i标签:声明 构造;分号是可选的,所以它不会抱怨它。

如果向对象添加另一个属性,它最终会抛出错误。

$ node -e "[1, 2, 3].map(v => {n: v, m: v+1});"
[1, 2, 3].map(v => {n: v, m: v+1});
                           ^

SyntaxError: Unexpected token :

I have found one difference, for ES6/ES2015. You cannot return an object using the shorthand arrow function syntax, unless you surround the object with new Object().

> [1, 2, 3].map(v => {n: v});
[ undefined, undefined, undefined ]
> [1, 2, 3].map(v => new Object({n: v}));
[ { n: 1 }, { n: 2 }, { n: 3 } ]

This is because the compiler is confused by the {} brackets and thinks n: i is a label: statement construct; the semicolon is optional so it doesn't complain about it.

If you add another property to the object it will finally throw an error.

$ node -e "[1, 2, 3].map(v => {n: v, m: v+1});"
[1, 2, 3].map(v => {n: v, m: v+1});
                           ^

SyntaxError: Unexpected token :
沫离伤花 2024-10-17 01:11:39

我唯一一次使用“new”关键字进行对象初始化是在内联箭头函数中:

() => new Object({ key: value})

因为以下代码无效:

() => { key: value} //  instead of () => { return { key: value};}

The only time i will use the 'new' keyowrd for object initialization is in inline arrow function:

() => new Object({ key: value})

since the below code is not valid:

() => { key: value} //  instead of () => { return { key: value};}
絕版丫頭 2024-10-17 01:11:39

这里有很多很好的答案,但我想拿出我的 50 美分。

所有这些答案都缺少一个简单的类比,这个类比对于刚刚开始编程语言之旅的人来说是有效的。

希望我能用这个类比来填补这个空白:

对象文字创建与基于构造函数的语法

感受句子创建的区别。

如果我有一句话“我喜欢奶酪”,我可以清楚而大声地告诉你(字面意思或逐字):我喜欢奶酪。

这是我按字面(逐字)创造的句子。

所有其他方法都是一些棘手的方法,可以让您准确地理解我创建的句子。例如,我告诉你:

  1. 在我的句子中,主语是“I”,宾语是“cheese”,谓语是“to like”
    这是您毫无歧义地学习同一句话的另一种方式:“我喜欢奶酪”。

或者,

  1. 我的句子有3个单词:第一个是英语词典中的第n个单词,第二个是英语词典中的第m个单词,最后一个是英语词典中的第l个单词。

在这种情况下,你也会得到相同的结果:你确切地知道这句话是什么。

您可以设计与“逐字”句子创建(LITERAL)不同的任何其他方法,以及间接(非字面、非逐字)句子创建方法。

我认为这就是这里的核心概念。

There are a lot of great answers here, but I want to come with my 50 cents.

What all of these answers are missing is a simple analogy which would work for a person who just starts his journey in the programming languages.

Hopefully, I will fill this gap with this analogy:

Object Literal Creation vs Constructor-based Syntax

Feel the difference with a sentence creation.

If I have a sentence "I like cheese", I can tell you clearly and loudly (literally, or verbatim): I like cheese.

This is my literal (word by word) creation of the sentence.

All other ways are some tricky ways of making you to understand of what sentence I created exactly. For example, I tell you:

  1. In my sentence, the subject is "I", the object is "cheese", and the predicate is "to like".
    This is another way of YOU to learn without any ambiguities the very same sentence: "I like cheese".

Or,

  1. My sentence has 3 words: the first one is the n-th word in the English dictionary, the the second one is the m-th word in the English dictionary and the last one is the l-th word in the English dictionary.

In this case, you also come to the same result: you know exactly what the sentence is.

You can devise any other methods which would differ from "word-by-word" sentence creation (LITERAL), and which would be INDIRECT (non literal, non verbatim) method of sentence creation.

I think this is the core concept which lays here.

冷…雨湿花 2024-10-17 01:11:39

如果我们尝试测量对象创建像这样 (替代链接):

const iterations = 10000

class MyObject {
  constructor() {
    this.a = 'a'
    this.b = 'b'
  }

  foo() {
    return 'foo'
  }
}

for (let i = 0; i < iterations; i++) {
  const objectLiteral = {a: 'a', b: 'b', foo() { return 'foo' }}
} 

for (let i = 0; i < iterations; i++) {
  const objectNew = new MyObject()
}

这会给你非常有趣的结果:
输入图片这里的描述

你可以看到,当我们执行多次>=100时,对象文字new MyObject()慢。

这种差异可以通过以下事实来解释:对象字面量消耗更多的内存和 CPU 来初始化每个对象唯一的 foo() 方法,而 MyObject 类共享单个 foo() 通过原型及其所有实例。

然而,当我们从测试中删除该方法时:

const iterations = 10000

class MyObject {
  constructor(id) {
    this.a = 'a'
    this.b = 'b'
    this.id = id
  }
}

for (let i = 0; i < iterations; i++) {
  const objectLiteral = {a: 'a', b: 'b', id: i}
}

for (let i = 0; i < iterations; i++) {
  const objectNew = new MyObject(i)
}

然后我们可以看到差异几乎消失了(基准):
输入图片此处描述

If we will try to measure objects creation like this (alternative link):

const iterations = 10000

class MyObject {
  constructor() {
    this.a = 'a'
    this.b = 'b'
  }

  foo() {
    return 'foo'
  }
}

for (let i = 0; i < iterations; i++) {
  const objectLiteral = {a: 'a', b: 'b', foo() { return 'foo' }}
} 

for (let i = 0; i < iterations; i++) {
  const objectNew = new MyObject()
}

Which will give you very interesting result:
enter image description here

You can see that the object literal is slower than new MyObject() when we do it multiple times >=100.

This difference can be explained by the fact that object literal consumes much more memory and CPU to initialize foo() method which is unique for each object, while the MyObject class shares a single foo() with all of its instances through the prototype.

However, when we remove the method from the test:

const iterations = 10000

class MyObject {
  constructor(id) {
    this.a = 'a'
    this.b = 'b'
    this.id = id
  }
}

for (let i = 0; i < iterations; i++) {
  const objectLiteral = {a: 'a', b: 'b', id: i}
}

for (let i = 0; i < iterations; i++) {
  const objectNew = new MyObject(i)
}

Then we can see that the difference almost disappears (benchmark):
enter image description here

只是一片海 2024-10-17 01:11:39

如果创建 10000 个实例,内存使用情况会有所不同。
new Object() 将仅保留一份副本,而 {} 将保留 10,000 个副本。

Memory usage is different if you create 10 thousand instances.
new Object() will only keep only one copy while {} will keep 10 thousand copies.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文