Heim  >  Artikel  >  Web-Frontend  >  Ein Artikel, der einige Betriebsmethoden von Object-Objekten in JS erklärt (Teilen)

Ein Artikel, der einige Betriebsmethoden von Object-Objekten in JS erklärt (Teilen)

奋力向前
奋力向前nach vorne
2021-08-20 10:27:502108Durchsuche

Im vorherigen Artikel „Eingehende Analyse der Objektkopiermethode in JavaScript (mit Code)“ haben wir etwas über die Objektkopiermethode in JS gelernt. Der folgende Artikel stellt Ihnen einige Betriebsmethoden von Object-Objekten in JS vor.

Ein Artikel, der einige Betriebsmethoden von Object-Objekten in JS erklärt (Teilen)

Einige effiziente Operationsmethoden für Object in javascript javascriptObject一些高效的操作方法

Object.assign()

方法用于将所有可枚举属性的值从一个或多个源对象复制到目标对象。它将返回目标对象。

const object1 = { a: 1, b: 2, c: 3 };
const object2 = Object.assign({ c: 4, d: 5 }, object1);
console.log(object2); // {  a: 1,  b: 2,  c: 3 ,c: 4, d: 5 }

Object.create()

方法创建一个新对象,使用现有的对象来提供新创建的对象的proto

const person = {
  color: "red",
  sayName: function () {
    console.log(this.name);
  },
};

const m = Object.create(person);
m.name = "chuchur";
m.sayName(); // chuchur

Object.defineProperties()

方法直接在一个对象上定义新的属性或修改现有属性,并返回该对象。

var obj = {};
Object.defineProperties(obj, {
  property1: {
    value: 1,
    writable: true,
  },
  property2: {
    value: "Hello",
    writable: false,
  },
});

obj.property1 = 1;
obj.property2 = 2;

console.log(obj); // {property1: 1, property2: "Hello"}

Object.defineProperty()

方法会直接在一个对象上定义一个新属性,或者修改一个对象的现有属性,并返回这个对象。

var o = {}; // 创建一个新对象

// 在对象中添加一个属性与数据描述符的示例
Object.defineProperty(o, "a", {
  value: 37,
  writable: true,
  enumerable: true,
  configurable: true,
});

// 对象o拥有了属性a,值为37

// 在对象中添加一个属性与存取描述符的示例
var bValue;
Object.defineProperty(o, "b", {
  get: function () {
    return bValue;
  },
  set: function (newValue) {
    bValue = newValue;
  },
  enumerable: true,
  configurable: true,
});

o.b = 38;
// 对象o拥有了属性b,值为38

// o.b的值现在总是与bValue相同,除非重新定义o.b

Object.entries()

方法返回一个给定对象自身可枚举属性的键值对数组,其排列与使用for...in循环遍历该对象时返回的顺序一致(区别在于for-in循环也枚举原型链中的属性)。

const obj = { foo: "bar", baz: 42 };
console.log(Object.entries(obj));
//[['foo','bar'],['baz',42]]

Object.keys()

方法会返回一个由一个给定对象的自身可枚举属性组成的数组,数组中属性名的排列顺序和使用for...in循环遍历该对象时返回的顺序一致 。

// simple array
var arr = ["a", "b", "c"];
console.log(Object.keys(arr)); // console: ['0', '1', '2']

// array like object
var obj = { 0: "a", 1: "b", 2: "c" };
console.log(Object.keys(obj)); // console: ['0', '1', '2']

// array like object with random key ordering
var anObj = { 100: "a", 2: "b", 7: "c" };
console.log(Object.keys(anObj)); // console: ['2', '7', '100']

// getFoo is a property which isn't enumerable
var myObj = Object.create(
  {},
  {
    getFoo: {
      value: function () {
        return this.foo;
      },
    },
  }
);
myObj.foo = 1;
console.log(Object.keys(myObj)); // console: ['foo']

Object.values()

方法返回一个给定对象自己的所有可枚举属性值的数组,值的顺序与使用for...in循环的顺序相同(区别在于for-in循环枚举原型链中的属性 )。

var obj = { foo: "bar", baz: 42 };
console.log(Object.values(obj)); // ['bar', 42]

// array like object
var obj = { 0: "a", 1: "b", 2: "c" };
console.log(Object.values(obj)); // ['a', 'b', 'c']

// array like object with random key ordering
// when we use numeric keys, the value returned in a numerical order according to the keys
var an_obj = { 100: "a", 2: "b", 7: "c" };
console.log(Object.values(an_obj)); // ['b', 'c', 'a']

// getFoo is property which isn't enumerable
var my_obj = Object.create(
  {},
  {
    getFoo: {
      value: function () {
        return this.foo;
      },
    },
  }
);
my_obj.foo = "bar";
console.log(Object.values(my_obj)); // ['bar']

// non-object argument will be coerced to an object
console.log(Object.values("foo")); // ['f', 'o', 'o'] ==Array.from('foo')

//ES5
if (!Object.values)
  Object.values = function (obj) {
    if (obj !== Object(obj))
      throw new TypeError("Object.values called on a non-object");
    var val = [],
      key;
    for (key in obj) {
      if (Object.prototype.hasOwnProperty.call(obj, key)) {
        val.push(obj[key]);
      }
    }
    return val;
  };

Object.hasOwnProperty()

方法会返回一个布尔值,指示对象自身属性中是否具有指定的属性。

o = new Object();
o.prop = "exists";

function changeO() {
  o.newprop = o.prop;
  delete o.prop;
}

o.hasOwnProperty("prop"); // 返回 true
changeO();
o.hasOwnProperty("prop"); // 返回 false
o.hasOwnProperty("toString"); // 返回 false
o.hasOwnProperty("hasOwnProperty"); // 返回 false

Object.getOwnPropertyDescriptor()

方法返回指定对象上一个自有属性对应的属性描述符。(自有属性指的是直接赋予该对象的属性,不需要从原型链上进行查找的属性)

o = { bar: 42 };
d = Object.getOwnPropertyDescriptor(o, "bar");
// d {
//   configurable: true,
//   enumerable: true,
//   value: 42,
//   writable: true
// }

Object.getOwnPropertyDescriptors()

方法用来获取一个对象的所有自身属性的描述符。

Object.assign()方法只能拷贝源对象的可枚举的自身属性,同时拷贝时无法拷贝属性的特性们,而且访问器属性会被转换成数据属性,也无法拷贝源对象的原型,该方法配合Object.create() 方法可以实现上面说的这些。

Object.create(
  Object.getPrototypeOf(obj),
  Object.getOwnPropertyDescriptors(obj)
);

Object.getOwnPropertyNames()

方法返回一个由指定对象的所有自身属性的属性名(包括不可枚举属性但不包括Symbol值作为名称的属性)组成的数组。

var arr = ["a", "b", "c"];
console.log(Object.getOwnPropertyNames(arr).sort()); // ["0", "1", "2", "length"]

// 类数组对象
var obj = { 0: "a", 1: "b", 2: "c" };
console.log(Object.getOwnPropertyNames(obj).sort()); // ["0", "1", "2"]

// 使用Array.forEach输出属性名和属性值
Object.getOwnPropertyNames(obj).forEach(function (val, idx, array) {
  console.log(val + " -> " + obj[val]);
});
// 输出
// 0 -> a
// 1 -> b
// 2 -> c

//不可枚举属性
var my_obj = Object.create(
  {},
  {
    getFoo: {
      value: function () {
        return this.foo;
      },
      enumerable: false,
    },
  }
);
my_obj.foo = 1;

console.log(Object.getOwnPropertyNames(my_obj).sort()); // ["foo", "getFoo"]

Object.getOwnPropertySymbols()

方法返回一个给定对象自身的所有Symbol属性的数组。

var obj = {};
var a = Symbol("a");
var b = Symbol.for("b");

obj[a] = "localSymbol";
obj[b] = "globalSymbol";

var objectSymbols = Object.getOwnPropertySymbols(obj);

console.log(objectSymbols.length); // 2
console.log(objectSymbols); // [Symbol(a), Symbol(b)]
console.log(objectSymbols[0]); // Symbol(a)

Object.isPrototypeOf()

方法用于测试一个对象是否存在于另一个对象的原型链上。

function Foo() {}
function Bar() {}
function Baz() {}

Bar.prototype = Object.create(Foo.prototype);
Baz.prototype = Object.create(Bar.prototype);

var baz = new Baz();

console.log(Baz.prototype.isPrototypeOf(baz)); // true
console.log(Bar.prototype.isPrototypeOf(baz)); // true
console.log(Foo.prototype.isPrototypeOf(baz)); // true
console.log(Object.prototype.isPrototypeOf(baz)); // true

Object.propertyIsEnumerable()

方法返回一个布尔值,表示指定的属性是否可枚举。

var o = {};
var a = [];
o.prop = "is enumerable";
a[0] = "is enumerable";

o.propertyIsEnumerable("prop"); //  返回 true
a.propertyIsEnumerable(0); // 返回 true

//用户自定义对象和引擎内置对象
var a = ["is enumerable"];

a.propertyIsEnumerable(0); // 返回 true
a.propertyIsEnumerable("length"); // 返回 false

Math.propertyIsEnumerable("random"); // 返回 false
this.propertyIsEnumerable("Math"); // 返回 false

//自身属性和继承属性
var a = [];
a.propertyIsEnumerable("constructor"); // 返回 false

function firstConstructor() {
  this.property = "is not enumerable";
}

firstConstructor.prototype.firstMethod = function () {};

function secondConstructor() {
  this.method = function method() {
    return "is enumerable";
  };
}

secondConstructor.prototype = new firstConstructor();
secondConstructor.prototype.constructor = secondConstructor;

var o = new secondConstructor();
o.arbitraryProperty = "is enumerable";

o.propertyIsEnumerable("arbitraryProperty"); // 返回 true
o.propertyIsEnumerable("method"); // 返回 true
o.propertyIsEnumerable("property"); // 返回 false

o.property = "is enumerable";

o.propertyIsEnumerable("property"); // 返回 true

// 这些返回fasle,是因为,在原型链上propertyIsEnumerable不被考虑
// (尽管最后两个在for-in循环中可以被循环出来)。
o.propertyIsEnumerable("prototype"); // 返回 false (根据 JS 1.8.1/FF3.6)
o.propertyIsEnumerable("constructor"); // 返回 false
o.propertyIsEnumerable("firstMethod"); // 返回 false

Object.getPrototypeOf()

方法返回指定对象的原型(内部[[Prototype]]

Object.assign()

Methode wird verwendet, um die Werte aller aufzählbaren Eigenschaften zuzuweisen von einem oder mehreren Quellobjekten werden in das Zielobjekt kopiert. Es wird das Zielobjekt zurückgegeben. Die Methode

const prototype1 = {};
const object1 = Object.create(prototype1);

console.log(Object.getPrototypeOf(object1) === prototype1);
// expected output: true

Object.create()

erstellt ein neues Objekt und verwendet ein vorhandenes Objekt, um den Proto des neu erstellten Objekts bereitzustellen. Die Methode

Object.is("foo", "foo"); // true
Object.is(window, window); // true

Object.is("foo", "bar"); // false
Object.is([], []); // false

var test = { a: 1 };
Object.is(test, test); // true

Object.is(null, null); // true

// 特例
Object.is(0, -0); // false
Object.is(-0, -0); // true
Object.is(NaN, 0 / 0); // true

// ES5
if (!Object.is) {
  Object.is = function (x, y) {
    // SameValue algorithm
    if (x === y) {
      // Steps 1-5, 7-10
      // Steps 6.b-6.e: +0 != -0
      return x !== 0 || 1 / x === 1 / y;
    } else {
      // Step 6.a: NaN == NaN
      return x !== x && y !== y;
    }
  };
}

Object.defineProperties()

definiert direkt neue Eigenschaften oder ändert vorhandene Eigenschaften eines Objekts und gibt das Objekt zurück.

// Object.preventExtensions将原对象变的不可扩展,并且返回原对象.
var obj = {};
var obj2 = Object.preventExtensions(obj);
obj === obj2; // true

// 字面量方式定义的对象默认是可扩展的.
var empty = {};
Object.isExtensible(empty); //=== true

// ...但可以改变.
Object.preventExtensions(empty);
Object.isExtensible(empty); //=== false

// 使用Object.defineProperty方法为一个不可扩展的对象添加新属性会抛出异常.
var nonExtensible = { removable: true };
Object.preventExtensions(nonExtensible);
Object.defineProperty(nonExtensible, "new", { value: 8675309 }); // 抛出TypeError异常

// 在严格模式中,为一个不可扩展对象的新属性赋值会抛出TypeError异常.
function fail() {
  "use strict";
  nonExtensible.newProperty = "FAIL"; // throws a TypeError
}
fail();

// 一个不可扩展对象的原型是不可更改的,__proto__是个非标准魔法属性,可以更改一个对象的原型.
var fixed = Object.preventExtensions({});
fixed.__proto__ = { oh: "hai" }; // 抛出TypeError异常

Object.defineProperty()

Die Methode definiert direkt eine neue Eigenschaft für ein Objekt oder ändert eine vorhandene Eigenschaft eines Objekts und gibt das Objekt zurück. Die Methode

// 新对象默认是可扩展的.
var empty = {};
Object.isExtensible(empty); // === true

// ...可以变的不可扩展.
Object.preventExtensions(empty);
Object.isExtensible(empty); // === false

// 密封对象是不可扩展的.
var sealed = Object.seal({});
Object.isExtensible(sealed); // === false

// 冻结对象也是不可扩展.
var frozen = Object.freeze({});
Object.isExtensible(frozen); // === false

Object.entries()

gibt ein Array von Schlüssel-Wert-Paaren für die eigenen aufzählbaren Eigenschaften des angegebenen Objekts zurück, die auf die gleiche Weise angeordnet sind wie die, die beim Durchlaufen des Objekts mit for...in zurückgegeben werden Die Reihenfolge ist dieselbe (der Unterschied besteht darin, dass die for-in-Schleife auch die Eigenschaften in der Prototypenkette aufzählt). Die Methode

const object1 = {
  property1: 42,
};

const object2 = Object.freeze(object1);

object2.property1 = 33;
// 严格模式会报错,非严格模式不报错,但是不执行

console.log(object2.property1);
// 输出: 42

Object.keys()

gibt ein Array zurück, das aus den selbstaufzählbaren Eigenschaften eines bestimmten Objekts besteht. Die Reihenfolge der Eigenschaftsnamen im Array und die Verwendung von for...in Die beim Durchlaufen des Objekts zurückgegebene Reihenfolge ist konsistent. Die Methode <p><pre class="brush:php;toolbar:false">// 使用Object.freeze是冻结一个对象最方便的方法. var frozen = { 1: 81 }; Object.isFrozen(frozen); //=== false Object.freeze(frozen); Object.isFrozen(frozen); //=== true // 一个冻结对象也是一个密封对象. Object.isSealed(frozen); //=== true // 当然,更是一个不可扩展的对象. Object.isExtensible(frozen); //=== false // 一个对象默认是可扩展的,所以它也是非冻结的. Object.isFrozen({}); // === false // 一个不可扩展的空对象同时也是一个冻结对象. var vacuouslyFrozen = Object.preventExtensions({}); Object.isFrozen(vacuouslyFrozen); //=== true; // 一个非空对象默认也是非冻结的. var oneProp = { p: 42 }; Object.isFrozen(oneProp); //=== false // 让这个对象变的不可扩展,并不意味着这个对象变成了冻结对象, // 因为p属性仍然是可以配置的(而且可写的). Object.preventExtensions(oneProp); Object.isFrozen(oneProp); //=== false // ...如果删除了这个属性,则它会成为一个冻结对象. delete oneProp.p; Object.isFrozen(oneProp); //=== true // 一个不可扩展的对象,拥有一个不可写但可配置的属性,则它仍然是非冻结的. var nonWritable = { e: &quot;plep&quot; }; Object.preventExtensions(nonWritable); Object.defineProperty(nonWritable, &quot;e&quot;, { writable: false }); // 变得不可写 Object.isFrozen(nonWritable); //=== false // 把这个属性改为不可配置,会让这个对象成为冻结对象. Object.defineProperty(nonWritable, &quot;e&quot;, { configurable: false }); // 变得不可配置 Object.isFrozen(nonWritable); //=== true // 一个不可扩展的对象,拥有一个不可配置但可写的属性,则它仍然是非冻结的. var nonConfigurable = { release: &quot;the kraken!&quot; }; Object.preventExtensions(nonConfigurable); Object.defineProperty(nonConfigurable, &quot;release&quot;, { configurable: false }); Object.isFrozen(nonConfigurable); //=== false // 把这个属性改为不可写,会让这个对象成为冻结对象. Object.defineProperty(nonConfigurable, &quot;release&quot;, { writable: false }); Object.isFrozen(nonConfigurable); //=== true // 一个不可扩展的对象,值拥有一个访问器属性,则它仍然是非冻结的. var accessor = { get food() { return &quot;yum&quot;; }, }; Object.preventExtensions(accessor); Object.isFrozen(accessor); //=== false // ...但把这个属性改为不可配置,会让这个对象成为冻结对象. Object.defineProperty(accessor, &quot;food&quot;, { configurable: false }); Object.isFrozen(accessor); //=== true</pre></p>Object.values()<h2></h2> gibt ein Array aller aufzählbaren Eigenschaftswerte eines bestimmten Objekts selbst zurück. Die Reihenfolge der Werte ist dieselbe wie bei Verwendung des <code>for...in-Schleife (der Unterschied besteht in einer <code>for-in-Schleife, die Eigenschaften in der Prototypenkette auflistet). Die Methode

const object1 = {
  property1: 42,
};

Object.seal(object1);
object1.property1 = 33;
console.log(object1.property1);
// expected output: 33

delete object1.property1; // cannot delete when sealed
console.log(object1.property1);
// expected output: 33

Object.hasOwnProperty()

gibt einen booleschen Wert zurück, der angibt, ob das Objekt die angegebene Eigenschaft in seinen eigenen Eigenschaften hat. Die Methode

// 新建的对象默认不是密封的.
var empty = {};
Object.isSealed(empty); // === false

// 如果你把一个空对象变的不可扩展,则它同时也会变成个密封对象.
Object.preventExtensions(empty);
Object.isSealed(empty); // === true

// 但如果这个对象不是空对象,则它不会变成密封对象,因为密封对象的所有自身属性必须是不可配置的.
var hasProp = { fee: "fie foe fum" };
Object.preventExtensions(hasProp);
Object.isSealed(hasProp); // === false

// 如果把这个属性变的不可配置,则这个对象也就成了密封对象.
Object.defineProperty(hasProp, "fee", { configurable: false });
Object.isSealed(hasProp); // === true

// 最简单的方法来生成一个密封对象,当然是使用Object.seal.
var sealed = {};
Object.seal(sealed);
Object.isSealed(sealed); // === true

// 一个密封对象同时也是不可扩展的.
Object.isExtensible(sealed); // === false

// 一个密封对象也可以是一个冻结对象,但不是必须的.
Object.isFrozen(sealed); // === true ,所有的属性都是不可写的
var s2 = Object.seal({ p: 3 });
Object.isFrozen(s2); // === false, 属性"p"可写

var s3 = Object.seal({
  get p() {
    return 0;
  },
});
Object.isFrozen(s3); // === true ,访问器属性不考虑可写不可写,只考虑是否可配置

Object.getOwnPropertyDescriptor()

gibt den Eigenschaftsdeskriptor zurück, der einer eigenen Eigenschaft für das angegebene Objekt entspricht. (Eigene Eigenschaften beziehen sich auf Eigenschaften, die dem Objekt direkt zugewiesen sind und nicht in der Prototypenkette nachgeschlagen werden müssen) Die Methode

// Array:返回数组对象本身
var array = ["ABC", true, 12, -5];
console.log(array.valueOf() === array); // true

// Date:当前时间距1970年1月1日午夜的毫秒数
var date = new Date(2013, 7, 18, 23, 11, 59, 230);
console.log(date.valueOf()); // 1376838719230

// Number:返回数字值
var num = 15.2654;
console.log(num.valueOf()); // 15.2654

// 布尔:返回布尔值true或false
var bool = true;
console.log(bool.valueOf() === bool); // true

// new一个Boolean对象
var newBool = new Boolean(true);
// valueOf()返回的是true,两者的值相等
console.log(newBool.valueOf() == newBool); // true
// 但是不全等,两者类型不相等,前者是boolean类型,后者是object类型
console.log(newBool.valueOf() === newBool); // false

// Function:返回函数本身
function foo() {}
console.log(foo.valueOf() === foo); // true
var foo2 = new Function("x", "y", "return x + y;");
console.log(foo2.valueOf());
/*
ƒ anonymous(x,y
) {
return x + y;
}
*/

// Object:返回对象本身
var obj = { name: "张三", age: 18 };
console.log(obj.valueOf() === obj); // true

// String:返回字符串值
var str = "http://www.xyz.com";
console.log(str.valueOf() === str); // true

// new一个字符串对象
var str2 = new String("http://www.xyz.com");
// 两者的值相等,但不全等,因为类型不同,前者为string类型,后者为object类型
console.log(str2.valueOf() === str2); // false

Object.getOwnPropertyDescriptors()🎜🎜 wird verwendet, um die Deskriptoren aller eigenen Eigenschaften von zu erhalten ein Objekt. 🎜🎜🎜Die Object.assign()-Methode kann nur die aufzählbaren eigenen Eigenschaften des Quellobjekts kopieren. Gleichzeitig können die Eigenschaften der Eigenschaften beim Kopieren nicht kopiert werden. und der Prototyp des Quellobjekts kann nicht kopiert werden. Diese Methode kann in Verbindung mit der Methode Object.create() verwendet werden, um das oben Gesagte zu erreichen. Die Methode 🎜🎜rrreee🎜Object.getOwnPropertyNames()🎜🎜 gibt ein Array zurück, das aus den Eigenschaftsnamen aller eigenen Eigenschaften des angegebenen Objekts besteht (einschließlich nicht aufzählbarer Eigenschaften, aber ausgenommen Eigenschaften mit Symbol-Werten). als Namen). Die Methode 🎜rrreee🎜Object.getOwnPropertySymbols()🎜🎜 gibt ein Array aller Symbol-Eigenschaften des angegebenen Objekts selbst zurück. Die Methode 🎜rrreee🎜Object.isPrototypeOf()🎜🎜 wird verwendet, um zu testen, ob ein Objekt in der Prototypenkette eines anderen Objekts vorhanden ist. Die Methode 🎜rrreee🎜Object.propertyIsEnumerable()🎜🎜 gibt einen booleschen Wert zurück, der angibt, ob die angegebene Eigenschaft aufzählbar ist. Die Methode 🎜rrreee🎜Object.getPrototypeOf()🎜🎜 gibt das Prototyp-Attribut (internal [[Prototype]] des angegebenen Objekts zurück. Die Methode 🎜rrreee🎜Object.is()🎜🎜 bestimmt, ob die beiden Werte sind gleichwertig. Die Methode 🎜rrreee🎜Object.preventExtensions()🎜🎜 macht ein Objekt nicht erweiterbar, d. h. es können nie neue Eigenschaften hinzugefügt werden. Die Methode 🎜rrreee🎜Object.isExtensible()🎜🎜 bestimmt, ob ein Objekt erweiterbar ist (ob ihm neue Eigenschaften hinzugefügt werden können). Die Methode 🎜rrreee🎜Object.freeze()🎜🎜 kann ein Objekt einfrieren. Das Einfrieren bedeutet, dass diesem Objekt keine neuen Attribute hinzugefügt werden können, die Werte vorhandener Attribute nicht geändert werden können, vorhandene Attribute nicht gelöscht werden können und das Objekt nicht Es gibt Aufzählbarkeit, Konfigurierbarkeit und Beschreibbarkeit von Eigenschaften. Diese Methode gibt das eingefrorene Objekt zurück. Die Methode 🎜rrreee🎜Object.isFrozen()🎜🎜 bestimmt, ob ein Objekt eingefroren ist. Die Methode 🎜rrreee🎜Object.seal()🎜🎜 versiegelt ein Objekt, verhindert das Hinzufügen neuer Eigenschaften und markiert alle vorhandenen Eigenschaften als nicht konfigurierbar. Der Wert der aktuellen Eigenschaft kann geändert werden, solange sie beschreibbar ist. Die Methode 🎜rrreee🎜Object.isSealed()🎜🎜 bestimmt, ob ein Objekt versiegelt ist. Die Methode 🎜rrreee🎜Object.valueOf()🎜🎜 gibt den ursprünglichen Wert des angegebenen Objekts zurück. 🎜rrreee🎜Empfohlenes Lernen: 🎜JavaScript-Video-Tutorial🎜🎜

Das obige ist der detaillierte Inhalt vonEin Artikel, der einige Betriebsmethoden von Object-Objekten in JS erklärt (Teilen). Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:chuchur.com. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen