จะรับคลาสของวัตถุ JavaScript ได้อย่างไร


728

ฉันสร้างวัตถุ JavaScript แต่ฉันจะกำหนดคลาสของวัตถุนั้นได้อย่างไร

ฉันต้องการบางสิ่งที่คล้ายกับ.getClass()วิธีของ Java


6
ตัวอย่างเช่นฉันสร้างคนเช่นนี้: var p = new Person (); ฉันมีวัตถุบุคคลที่เรียกว่า "p" ฉันจะใช้ "p" เพื่อเรียกคืนชื่อคลาสได้อย่างไร: "บุคคล"
DNB5brims


อัปเดต: ตั้งแต่วันที่ ECMAScript 6 JavaScript ยังไม่มีclassประเภท มันจะมีclassคำหลักและไวยากรณ์สำหรับการสร้างต้นแบบที่วิธีการที่สามารถเข้าถึงได้ง่ายมากขึ้นclass super
james_womack

สิ่งที่เกี่ยวกับ Object.className
Paul Basenko

@ Paul-Basenko: "className" จะไม่บอกคลาสของวัตถุ แต่จะส่งคืนเนื้อหาของคุณสมบัติ "class" ขององค์ประกอบ HTML ซึ่งหมายถึงคลาส CSS คุณต้องการใช้ "classList" เพื่อจัดการได้อย่างง่ายดาย แต่ไม่เกี่ยวข้องกับคำถามของ OP
Obsidian

คำตอบ:


1009

ไม่มีคู่แน่นอนที่จะเป็นของ Java getClass()ใน JavaScript ส่วนใหญ่ว่าเนื่องจากเป็นจาวาสคริปต์ภาษาต้นแบบที่ใช้เมื่อเทียบกับ Java เป็นระดับที่ใช้อย่างใดอย่างหนึ่ง

getClass()JavaScript มีตัวเลือกหลายอย่างขึ้นอยู่กับสิ่งที่คุณต้องการ:

ตัวอย่างบางส่วน:

function Foo() {}
var foo = new Foo();

typeof Foo;             // == "function"
typeof foo;             // == "object"

foo instanceof Foo;     // == true
foo.constructor.name;   // == "Foo"
Foo.name                // == "Foo"    

Foo.prototype.isPrototypeOf(foo);   // == true

Foo.prototype.bar = function (x) {return x+x;};
foo.bar(21);            // == 42

หมายเหตุ: หากคุณกำลังรวบรวมรหัสของคุณด้วย Uglify มันจะเปลี่ยนชื่อคลาสที่ไม่ใช่สากล เพื่อป้องกันการนี้ทำให้น่าเกลียดมี--mangleพารามิเตอร์ที่คุณสามารถตั้งค่าเป็นเท็จจะใช้อึกหรือทำเสียงฮึดฮัด


6
ที่ควรจะเป็นfunc.prototype(ใช่ฟังก์ชั่นเป็นวัตถุ แต่prototypeคุณสมบัติมีความเกี่ยวข้องเฉพาะกับฟังก์ชั่นวัตถุ)
ไมล์

5
คุณอาจต้องการพูดถึงinstanceof/ isPrototypeOf()และที่ไม่ได้มาตรฐาน__proto__
Christoph

9
ES5 มีตามปกติObject.getPrototypeOf()
Christoph

22
คำเตือน : อย่าพึ่งพาconstructor.nameหากโค้ดของคุณถูกย่อขนาด ชื่อฟังก์ชั่นกำลังจะเปลี่ยนไปโดยพลการ
igorsantos07

3
@ igorsantos07 อย่างน้อยในปี 2562; ผลลัพธ์ 5-10 อันดับแรกของ Google สำหรับ "online javascript minifier" จะรับรู้construction.nameเป็นโทเค็นที่จะถูกละเว้น / ไม่ย่อเล็กสุด นอกจากนี้ซอฟต์แวร์ตัวขยายส่วนใหญ่ (ถ้าไม่ใช่ทั้งหมด) ยังมีกฎข้อยกเว้น
Raven vulcan

296
obj.constructor.name

เป็นวิธีการที่เชื่อถือได้ในเบราว์เซอร์ที่ทันสมัย Function.nameได้รับการเพิ่มอย่างเป็นทางการในมาตรฐานใน ES6 ทำให้นี่เป็นวิธีที่ได้มาตรฐานในการรับ "class" ของวัตถุ JavaScript เป็นสตริง ถ้าวัตถุนั้นถูกสร้างด้วยvar obj = new MyClass()มันจะส่งคืน "MyClass"

มันจะคืนค่า "Number" สำหรับตัวเลข "Array" สำหรับ Array และ "Function" สำหรับฟังก์ชั่น ฯลฯ โดยทั่วไปจะทำงานได้ตามปกติ เฉพาะกรณีที่มันล้มเหลวคือถ้าวัตถุถูกสร้างขึ้นโดยไม่มีต้นแบบผ่านObject.create( null )หรือวัตถุถูกยกตัวอย่างจากฟังก์ชั่นที่กำหนดโดยไม่ระบุชื่อ (ไม่มีชื่อ)

โปรดทราบว่าหากคุณกำลังลดขนาดโค้ดของคุณคุณไม่ควรเปรียบเทียบกับสตริงประเภทที่มีการกำหนดรหัสยาก ยกตัวอย่างเช่นแทนการตรวจสอบถ้าแทนที่จะตรวจสอบobj.constructor.name == "MyType" obj.constructor.name == MyType.nameหรือเพียงเปรียบเทียบตัวสร้างเอง แต่สิ่งนี้จะไม่ทำงานข้ามขอบเขต DOM เนื่องจากมีอินสแตนซ์ที่แตกต่างกันของฟังก์ชันตัวสร้างในแต่ละ DOM ดังนั้นการเปรียบเทียบวัตถุบนตัวสร้างจะไม่ทำงาน


11
Function.nameยังไม่ได้เป็นส่วนหนึ่งของมาตรฐาน JavaScript ขณะนี้รองรับ Chrome และ Firefox แต่ไม่รองรับ IE (10)
Halcyon

13
obj.constructor.nameใช้ได้กับฟังก์ชั่นที่ตั้งชื่อเท่านั้น เช่นถ้าฉันกำหนดvar Foo = function() {}แล้วสำหรับvar foo = new Foo(), foo.constructor.nameจะทำให้คุณสตริงที่ว่างเปล่า
KFL

29
คำเตือน : อย่าพึ่งพาconstructor.nameหากโค้ดของคุณถูกย่อขนาด ชื่อฟังก์ชั่นกำลังจะเปลี่ยนไปโดยพลการ
igorsantos07

1
Function.name เป็นส่วนหนึ่งของ ES6 โปรดดูdeveloper.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
Janus Troelsen

1
@adalbertpl มันเกี่ยวข้องกับต้นแบบการผูกมัดตนเองก่อน ES6 เป็นการดีที่จะรู้ว่าconstructor.nameพฤติกรรมจะเป็นไปตามที่คาดไว้ด้วยการสนับสนุนคลาสใหม่ใน ES6
devios1

29

ฟังก์ชันนี้ส่งคืน"Undefined"ค่าที่ไม่ได้กำหนดและ"Null"ค่าว่าง
สำหรับค่าอื่น ๆ ทุกCLASSNAME-part สกัดจากซึ่งเป็นผลมาจากการใช้[object CLASSNAME]Object.prototype.toString.call(value)

function getClass(obj) {
  if (typeof obj === "undefined") return "Undefined";
  if (obj === null) return "Null";
  return Object.prototype.toString.call(obj).match(/^\[object\s(.*)\]$/)[1];
}

getClass("")   === "String";
getClass(true) === "Boolean";
getClass(0)    === "Number";
getClass([])   === "Array";
getClass({})   === "Object";
getClass(null) === "Null";
// etc...

Object.prototype.getClass = ฟังก์ชั่น () {ใช้ 'this' แทน obj จะดี
SparK

2
แน่นอนแล้ว null และ undefined จะไม่สามารถตรวจสอบได้เนื่องจาก Object จะมีเมธอด getClass
SparK

8
ใช้งานได้กับวัตถุดั้งเดิมเท่านั้น "Object"หากคุณมีชนิดของการถ่ายทอดทางพันธุกรรมบางอย่างไปคุณก็จะได้รับ
Halcyon

return obj.constructor.nameใช่บรรทัดสุดท้ายของการทำงานก็ควรจะเป็น ที่ให้ผลลัพธ์เดียวกันรวมทั้งจัดการกับวัตถุที่ไม่ใช่ของพื้นเมือง
Steve Bennett

18

ในการรับ "คลาสหลอก" คุณสามารถรับฟังก์ชัน Constructor ได้โดย

obj.constructor

สมมติว่าconstructorมีการตั้งค่าอย่างถูกต้องเมื่อคุณทำการรับมรดก - ซึ่งเป็นโดยสิ่งที่ชอบ:

Dog.prototype = new Animal();
Dog.prototype.constructor = Dog;

และทั้งสองบรรทัดพร้อมกับ:

var woofie = new Dog()

จะทำให้ชี้ไปที่woofie.constructor Dogโปรดทราบว่าDogเป็นฟังก์ชั่นการสร้างและเป็นFunctionวัตถุ if (woofie.constructor === Dog) { ... }แต่คุณสามารถทำ

หากคุณต้องการรับชื่อคลาสเป็นสตริงฉันพบว่าทำงานได้ดีดังต่อไปนี้:

http://blog.magnetiq.com/post/514962277/finding-out-class-names-of-javascript-objects

function getObjectClass(obj) {
    if (obj && obj.constructor && obj.constructor.toString) {
        var arr = obj.constructor.toString().match(
            /function\s*(\w+)/);

        if (arr && arr.length == 2) {
            return arr[1];
        }
    }

    return undefined;
}

มันจะได้รับฟังก์ชั่นคอนสตรัคแปลงเป็นสตริงและแยกชื่อของฟังก์ชั่นคอนสตรัค

โปรดทราบว่าobj.constructor.nameอาจทำงานได้ดี แต่ไม่ได้มาตรฐาน มันอยู่ใน Chrome และ Firefox แต่ไม่ใช่ใน IE รวมถึง IE 9 หรือ IE 10 RTM


13

คุณสามารถรับการอ้างอิงถึงฟังก์ชั่นคอนสตรัคซึ่งสร้างวัตถุโดยใช้คุณสมบัติคอนสตรัค :

function MyObject(){
}

var obj = new MyObject();
obj.constructor; // MyObject

หากคุณต้องการยืนยันประเภทของวัตถุที่รันไทม์คุณสามารถใช้ตัวดำเนินการinstanceof :

obj instanceof MyObject // true

มันไม่ส่งคืนฟังก์ชันคอนสตรัคเตอร์เองเช่นคุณสามารถเรียกมันอีกครั้งและสร้างวัตถุใหม่ของประเภทนั้นได้หรือไม่
SparK

1
@SparK ใช่แม้ว่าคุณยังคงสามารถใช้สิ่งนี้เพื่อการเปรียบเทียบตราบใดที่คุณอยู่ใน DOM เดียวกัน (คุณกำลังเปรียบเทียบวัตถุฟังก์ชัน) อย่างไรก็ตามมันเป็นวิธีปฏิบัติที่ดีกว่ามากในการเปลี่ยน Constructor ให้เป็นสตริงและเปรียบเทียบโดยเฉพาะเนื่องจากมันทำงานข้ามขอบเขต DOM เมื่อใช้ iframes
devios1

คำตอบนี้ส่งคืน "class" (หรืออย่างน้อยจัดการกับวัตถุที่สามารถใช้ในการสร้างตัวอย่างของคลาส - ซึ่งเป็นเช่นเดียวกับ "ชั้น") ข้างต้นตอบกลับสตริงทั้งหมดที่ไม่เหมือนกับ "คลาสวัตถุ" (เหมือนเดิม)
Mike P.

8

เพื่อให้สอดคล้องกับบันทึกที่ไม่สามารถย้อนกลับได้ของความเข้ากันได้ย้อนหลัง ECMAScript 6, JavaScript ยังไม่มีclassประเภท (แม้ว่าทุกคนจะไม่เข้าใจสิ่งนี้) มันจะมีclassคำหลักที่เป็นส่วนหนึ่งของclassไวยากรณ์สำหรับการสร้างต้นแบบ แต่ยังไม่มีสิ่งที่เรียกว่าระดับ JavaScript ไม่ใช่ตอนนี้และไม่เคยเป็นภาษา OOP แบบดั้งเดิมเลย การพูดของ JS ในแง่ของคลาสเป็นเพียงการทำให้เข้าใจผิดหรือเป็นสัญญาณว่ายังไม่ได้สืบทอดมรดกต้นแบบ (เพียงแค่ทำให้มันเป็นจริง)

นั่นหมายความว่าthis.constructorยังคงเป็นวิธีที่ดีในการรับconstructorฟังก์ชั่นอ้างอิง และthis.constructor.prototypeเป็นวิธีการเข้าถึงต้นแบบนั้นเอง เนื่องจากนี่ไม่ใช่ Java จึงไม่ใช่คลาส มันเป็นวัตถุต้นแบบที่อินสแตนซ์ของคุณยกตัวอย่าง นี่คือตัวอย่างการใช้น้ำตาล syntactic ES6 สำหรับการสร้างห่วงโซ่ต้นแบบ:

class Foo {
  get foo () {
    console.info(this.constructor, this.constructor.name)
    return 'foo'
  }
}

class Bar extends Foo {
  get foo () {
    console.info('[THIS]', this.constructor, this.constructor.name, Object.getOwnPropertyNames(this.constructor.prototype))
    console.info('[SUPER]', super.constructor, super.constructor.name, Object.getOwnPropertyNames(super.constructor.prototype))

    return `${super.foo} + bar`
  }
}

const bar = new Bar()
console.dir(bar.foo)

นี่คือผลลัพธ์ที่ใช้babel-node:

> $ babel-node ./foo.js                                                                                                                    6.2.0 master ●]
[THIS] [Function: Bar] 'Bar' [ 'constructor', 'foo' ]
[SUPER] [Function: Foo] 'Foo' [ 'constructor', 'foo' ]
[Function: Bar] 'Bar'
'foo + bar'

ที่นั่นคุณมีมัน! ในปี 2559 มีclassคำหลักใน JavaScript แต่ยังไม่มีประเภทชั้นเรียน this.constructorเป็นวิธีที่ดีที่สุดในการรับฟังก์ชั่น Constructor this.constructor.prototypeวิธีที่ดีที่สุดในการเข้าถึงตัวต้นแบบ


7

ฉันมีสถานการณ์ที่ต้องใช้งานทั่วไปตอนนี้และใช้สิ่งนี้:

class Test {
  // your class definition
}

nameByType = function(type){
  return type.prototype["constructor"]["name"];
};

console.log(nameByType(Test));

นั่นเป็นวิธีเดียวที่ฉันพบเพื่อให้ได้ชื่อคลาสตามประเภทอินพุตหากคุณไม่มีอินสแตนซ์ของวัตถุ

(เขียนใน ES2017)

สัญกรณ์ดอทยังใช้งานได้ดี

console.log(Test.prototype.constructor.name); // returns "Test" 

อานี่คือสิ่งที่ฉันกำลังมองหา หากยังไม่ได้สร้างอินสแตนซ์คุณต้องใช้ 'ต้น' เพื่อรับชื่อคลาส ขอบคุณตัน!
Artokun

4

สำหรับ Javascript Classes ใน ES6 คุณสามารถobject.constructorใช้ได้ ในคลาสตัวอย่างด้านล่างgetClass()เมธอดส่งคืนคลาส ES6 ตามที่คุณต้องการ:

var Cat = class {

    meow() {

        console.log("meow!");

    }

    getClass() {

        return this.constructor;

    }

}

var fluffy = new Cat();

...

var AlsoCat = fluffy.getClass();
var ruffles = new AlsoCat();

ruffles.meow();    // "meow!"

หากคุณยกตัวอย่างคลาสจากgetClassวิธีการตรวจสอบให้แน่ใจว่าคุณห่อในวงเล็บเช่นruffles = new ( fluffy.getClass() )( args... );


3

ฉันพบการobject.constructor.toString()ส่งคืน[object objectClass]ใน IE แทนที่จะfunction objectClass () {}ส่งคืนใน chome ดังนั้นฉันคิดว่ารหัสในhttp://blog.magnetiq.com/post/514962277/finding-out-class-names-of-javascript-objectsอาจทำงานได้ไม่ดีใน IE.A และฉันแก้ไขรหัสดังนี้:

รหัส:

var getObjectClass = function (obj) {
        if (obj && obj.constructor && obj.constructor.toString()) {

                /*
                 *  for browsers which have name property in the constructor
                 *  of the object,such as chrome 
                 */
                if(obj.constructor.name) {
                    return obj.constructor.name;
                }
                var str = obj.constructor.toString();
                /*
                 * executed if the return of object.constructor.toString() is 
                 * "[object objectClass]"
                 */

                if(str.charAt(0) == '[')
                {
                        var arr = str.match(/\[\w+\s*(\w+)\]/);
                } else {
                        /*
                         * executed if the return of object.constructor.toString() is 
                         * "function objectClass () {}"
                         * for IE Firefox
                         */
                        var arr = str.match(/function\s*(\w+)/);
                }
                if (arr && arr.length == 2) {
                            return arr[1];
                        }
          }
          return undefined; 
    };

2

ในจาวาสคริปต์ไม่มีคลาส แต่ฉันคิดว่าคุณต้องการชื่อคอนสตรัคเตอร์และobj.constructor.toString()จะบอกสิ่งที่คุณต้องการ


1
นี่จะคืนค่านิยามทั้งหมดของฟังก์ชัน constructor เป็นสตริง .nameสิ่งที่คุณต้องการจริงๆคือ
devios1

4
แต่.nameไม่ได้กำหนดไว้แม้ใน IE 9
nonopolarity

1

เห็นด้วยกับ dfa นั่นเป็นเหตุผลว่าทำไมฉันถึงถือว่า prototye เป็นคลาสเมื่อไม่พบชื่อคลาส

นี่คือฟังก์ชั่นที่ได้รับการอัพเกรดของอีไลเกรย์ที่โพสต์โดย Eli Gray เพื่อให้เข้ากับความคิดของฉัน

function what(obj){
    if(typeof(obj)==="undefined")return "undefined";
    if(obj===null)return "Null";
    var res = Object.prototype.toString.call(obj).match(/^\[object\s(.*)\]$/)[1];
    if(res==="Object"){
        res = obj.constructor.name;
        if(typeof(res)!='string' || res.length==0){
            if(obj instanceof jQuery)return "jQuery";// jQuery build stranges Objects
            if(obj instanceof Array)return "Array";// Array prototype is very sneaky
            return "Object";
        }
    }
    return res;
}

1

หากคุณต้องการไม่เพียง แต่จะได้รับคลาส แต่ยังขยายออกจากการมีเพียงตัวอย่างเขียน:

มามีกัน

 class A{ 
   constructor(name){ 
     this.name = name
   }
 };

 const a1 = new A('hello a1');

ดังนั้นการขยาย A ที่มีอินสแตนซ์เท่านั้นใช้:

const a2 = new ((Object.getPrototypeOf(a)).constructor())('hello a2')
// the analog of const a2 = new A()

console.log(a2.name)//'hello a2'

0

ฉันแนะนำให้ใช้Object.prototype.constructor.name:

Object.defineProperty(Object.prototype, "getClass", {
    value: function() {
      return this.constructor.name;
    }
});

var x = new DOMParser();
console.log(x.getClass()); // `DOMParser'

var y = new Error("");
console.log(y.getClass()); // `Error'

0

นี่คือการดำเนินการของ getClass()และgetInstance()

คุณสามารถรับการอ้างอิงสำหรับคลาสของวัตถุโดยใช้ this.constructorคุณสามารถที่จะได้รับการอ้างอิงสำหรับการเรียนของวัตถุโดยใช้

จากบริบทอินสแตนซ์:

function A() {
  this.getClass = function() {
    return this.constructor;
  }

  this.getNewInstance = function() {
    return new this.constructor;
  }
}

var a = new A();
console.log(a.getClass());  //  function A { // etc... }

// you can even:
var b = new (a.getClass());
console.log(b instanceof A); // true
var c = a.getNewInstance();
console.log(c instanceof A); // true

จากบริบทแบบคงที่:

function A() {};

A.getClass = function() {
  return this;
}

A.getInstance() {
  return new this;
}

2
ทำไมไม่เป็นเช่นนั้นthis.constructor?
โซโลมอน Ucko

1
ฉันไม่รู้ แต่ถ้าดีกว่าคุณสามารถแก้ไขคำตอบเพื่อปรับปรุงได้อย่างแน่นอนเมื่อคุณพบว่าดีขึ้นหลังจากทั้งหมดนี้เป็นชุมชน
Bruno Finger

0

คุณสามารถทำอะไรเช่นนี้

 class Hello {
     constructor(){
     }
    }
    
      function isClass (func) {
        return typeof func === 'function' && /^class\s/.test(Function.prototype.toString.call(func))
    }
    
   console.log(isClass(Hello))

สิ่งนี้จะบอกคุณว่าอินพุตเป็นคลาสหรือไม่


-2

Javascript เป็นภาษาที่ไม่มีคลาส: ไม่มีคลาสที่กำหนดพฤติกรรมของคลาสแบบสแตติกใน Java JavaScript ใช้ต้นแบบแทนคลาสเพื่อกำหนดคุณสมบัติของวัตถุรวมถึงวิธีการและการสืบทอด มันเป็นไปได้ที่จะจำลองคุณสมบัติตามคลาสด้วยต้นแบบใน JavaScript


12
ฉันได้มักจะกล่าวว่า Javascript ขาดระดับ :)
สตีเว่น

4
อัปเดต: ตั้งแต่วันที่ ECMAScript 6 JavaScript ยังไม่มีclassประเภท มันจะมีclassคำหลักและไวยากรณ์สำหรับการสร้างต้นแบบที่วิธีการที่สามารถเข้าถึงได้ง่ายมากขึ้นclass super
james_womack

-3

ดูเหมือนว่าจะตอบคำถามแล้ว แต่ OP ต้องการเข้าถึงคลาสและวัตถุเช่นเดียวกับที่เราทำใน Java และคำตอบที่เลือกนั้นไม่เพียงพอ (imho)

ด้วยคำอธิบายต่อไปนี้เราสามารถรับคลาสของวัตถุ (จริง ๆ แล้วเรียกว่าต้นแบบในจาวาสคริปต์)

var arr = new Array('red', 'green', 'blue');
var arr2 = new Array('white', 'black', 'orange');

คุณสามารถเพิ่มคุณสมบัติเช่นนี้:

Object.defineProperty(arr,'last', {
  get: function(){
    return this[this.length -1];
  }
});
console.log(arr.last) // blue

แต่.lastคุณสมบัติจะใช้ได้เฉพาะกับarrวัตถุ "" ซึ่งได้รับการยกตัวอย่างจากต้นแบบ Array ดังนั้นเพื่อให้.lastคุณสมบัติพร้อมใช้งานสำหรับวัตถุทั้งหมดที่อินสแตนซ์จาก Array prototype เราต้องกำหนด.lastคุณสมบัติสำหรับ Array prototype:

Object.defineProperty(Array.prototype,'last', {
  get: function(){
    return this[this.length -1];
  }
});
console.log(arr.last) // blue
console.log(arr2.last) // orange

ปัญหาคือคุณต้องรู้ว่าออบเจ็กต์ (ต้นแบบ) ตัวใดเป็นตัวแปร ' arr' และ ' arr2'! กล่าวอีกนัยหนึ่งถ้าคุณไม่ทราบประเภทคลาส (ต้นแบบ) ของarrวัตถุ '' คุณจะไม่สามารถกำหนดคุณสมบัติให้กับพวกเขาได้ ในตัวอย่างข้างต้นเรารู้ว่า arr เป็นอินสแตนซ์ของวัตถุ Array นั่นคือสาเหตุที่เราใช้ Array.prototype เพื่อกำหนดคุณสมบัติสำหรับ Array แต่ถ้าเราไม่รู้คลาส (ต้นแบบ) ของ ' arr'

Object.defineProperty(arr.__proto__,'last2', {
  get: function(){
    return this[this.length -1];
  }
});
console.log(arr.last) // blue
console.log(arr2.last) // orange

ดังที่คุณเห็นโดยไม่ทราบว่า ' arr' เป็นอาเรย์เราสามารถเพิ่มคุณสมบัติใหม่เพียงแค่อ้างอิงถึงคลาสของ ' arr' โดยใช้ ' arr.__proto__'

เราเข้าถึงต้นแบบของ ' arr' โดยไม่ทราบว่ามันเป็นตัวอย่างของ Array และฉันคิดว่านั่นคือสิ่งที่ OP ขอ


__proto__คุณสมบัติจะเลิกและมีเกือบจะไม่มีประโยชน์มากกว่าprototypeทรัพย์สิน
Sapphire_Brick
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.