Có JavaScript tương đương với Java s' class.getName()
?
Có JavaScript tương đương với Java s' class.getName()
?
Câu trả lời:
Có JavaScript tương đương với Java
class.getName()
không?
Không .
Cập nhật ES2015 : tên của class Foo {}
làFoo.name
. Tên của thing
lớp, bất kể thing
loại nào, là thing.constructor.name
. Các nhà xây dựng dựng sẵn trong môi trường ES2015 có thuộc tính chính xác name
; ví dụ (2).constructor.name
là "Number"
.
Nhưng đây là những bản hack khác nhau mà tất cả đều rơi xuống bằng cách này hay cách khác:
Đây là một bản hack sẽ làm những gì bạn cần - lưu ý rằng nó sửa đổi nguyên mẫu của Object, thứ mà mọi người cau mày (thường là vì lý do chính đáng)
Object.prototype.getName = function() {
var funcNameRegex = /function (.{1,})\(/;
var results = (funcNameRegex).exec((this).constructor.toString());
return (results && results.length > 1) ? results[1] : "";
};
Bây giờ, tất cả các đối tượng của bạn sẽ có hàm, getName()
sẽ trả về tên của hàm tạo dưới dạng một chuỗi. Tôi đã thử nghiệm điều này FF3
và IE7
, tôi không thể nói cho các triển khai khác.
Nếu bạn không muốn làm điều đó, đây là một cuộc thảo luận về các cách xác định các loại khác nhau trong JavaScript ...
Gần đây tôi đã cập nhật điều này để hoàn thiện hơn một chút, mặc dù điều đó khó xảy ra. Sửa chữa chào mừng ...
constructor
tài sản ...Mỗi cái đều object
có một giá trị cho thuộc tính của nó constructor
, nhưng tùy thuộc vào cách nó object
được xây dựng cũng như những gì bạn muốn làm với giá trị đó, nó có thể có hoặc không hữu ích.
Nói chung, bạn có thể sử dụng thuộc constructor
tính để kiểm tra loại đối tượng như vậy:
var myArray = [1,2,3];
(myArray.constructor == Array); // true
Vì vậy, nó hoạt động đủ tốt cho hầu hết các nhu cầu. Mà nói...
Sẽ không hoạt động TẠI TẤT CẢ trong nhiều trường hợp
Mẫu này, mặc dù bị hỏng, khá phổ biến:
function Thingy() {
}
Thingy.prototype = {
method1: function() {
},
method2: function() {
}
};
Objects
xây dựng thông qua new Thingy
sẽ có một constructor
tài sản mà trỏ đến Object
, không Thingy
. Vì vậy, chúng tôi rơi ngay từ đầu; bạn chỉ đơn giản là không thể tin tưởng constructor
vào một cơ sở mã mà bạn không kiểm soát.
Đa kế thừa
Một ví dụ không rõ ràng là sử dụng nhiều kế thừa:
function a() { this.foo = 1;}
function b() { this.bar = 2; }
b.prototype = new a(); // b inherits from a
Mọi thứ bây giờ không hoạt động như bạn có thể mong đợi:
var f = new b(); // instantiate a new object with the b constructor
(f.constructor == b); // false
(f.constructor == a); // true
Vì vậy, bạn có thể nhận được kết quả không mong muốn nếu object
thử nghiệm của bạn có một object
bộ khác prototype
. Có nhiều cách xung quanh vấn đề này ngoài phạm vi của cuộc thảo luận này.
Có những cách sử dụng khác cho constructor
tài sản, một số trong số chúng thú vị, một số khác không quá nhiều; bây giờ chúng tôi sẽ không đi sâu vào những sử dụng đó vì nó không liên quan đến cuộc thảo luận này.
Sẽ không làm việc chéo khung và cửa sổ chéo
Việc sử dụng .constructor
để kiểm tra loại sẽ bị hỏng khi bạn muốn kiểm tra loại đối tượng đến từ các window
đối tượng khác nhau , giả sử đó là iframe hoặc cửa sổ bật lên. Điều này là do có một phiên bản khác nhau của từng loại lõi constructor
trong mỗi 'cửa sổ', nghĩa là
iframe.contentWindow.Array === Array // false
instanceof
toán tử ...Các instanceof
nhà điều hành là một cách sạch sẽ thử nghiệm object
loại là tốt, nhưng có vấn đề về tiềm năng riêng của mình, giống như constructor
bất động sản.
var myArray = [1,2,3];
(myArray instanceof Array); // true
(myArray instanceof Object); // true
Nhưng instanceof
không hoạt động cho các giá trị nghĩa đen (vì nghĩa đen là không Objects
)
3 instanceof Number // false
'abc' instanceof String // false
true instanceof Boolean // false
Các chữ cần phải được bọc trong một Object
theo thứ tự cho instanceof
đến công việc, ví dụ
new Number(3) instanceof Number // true
Các .constructor
kiểm tra hoạt động tốt cho literals vì .
phương pháp gọi trình ngầm kết thúc tốt đẹp các literals trong loại đối tượng tương ứng của họ
3..constructor === Number // true
'abc'.constructor === String // true
true.constructor === Boolean // true
Tại sao hai dấu chấm cho 3? Bởi vì Javascript diễn giải dấu chấm đầu tiên dưới dạng dấu thập phân;)
instanceof
cũng sẽ không hoạt động trên các cửa sổ khác nhau, vì lý do tương tự như constructor
kiểm tra tài sản.
name
tài sản của constructor
tài sản ...Một lần nữa, xem ở trên; nó khá phổ biến đối với constructor
việc hoàn toàn sai lầm và hoàn toàn sai lầm và vô dụng.
Việc sử dụng myObjectInstance.constructor.name
sẽ cung cấp cho bạn một chuỗi chứa tên của constructor
hàm được sử dụng, nhưng phải chịu sự cảnh báo về thuộc constructor
tính đã được đề cập trước đó.
Đối với IE9 trở lên, bạn có thể hỗ trợ khỉ :
if (Function.prototype.name === undefined && Object.defineProperty !== undefined) {
Object.defineProperty(Function.prototype, 'name', {
get: function() {
var funcNameRegex = /function\s+([^\s(]+)\s*\(/;
var results = (funcNameRegex).exec((this).toString());
return (results && results.length > 1) ? results[1] : "";
},
set: function(value) {}
});
}
Phiên bản cập nhật từ bài viết trong câu hỏi. Điều này đã được thêm 3 tháng sau khi bài báo được xuất bản, đây là phiên bản được đề xuất để sử dụng bởi tác giả của bài báo Matthew Scharley. Thay đổi này được lấy cảm hứng từ các bình luận chỉ ra những cạm bẫy tiềm ẩn trong mã trước đó.
if (Function.prototype.name === undefined && Object.defineProperty !== undefined) {
Object.defineProperty(Function.prototype, 'name', {
get: function() {
var funcNameRegex = /function\s([^(]{1,})\(/;
var results = (funcNameRegex).exec((this).toString());
return (results && results.length > 1) ? results[1].trim() : "";
},
set: function(value) {}
});
}
Hóa ra, như chi tiết bài đăng này , bạn có thể sử dụng Object.prototype.toString
- mức độ thấp và triển khai chung của toString
- để lấy loại cho tất cả các loại tích hợp
Object.prototype.toString.call('abc') // [object String]
Object.prototype.toString.call(/abc/) // [object RegExp]
Object.prototype.toString.call([1,2,3]) // [object Array]
Người ta có thể viết một hàm trợ giúp ngắn như
function type(obj){
return Object.prototype.toString.call(obj).slice(8, -1);
}
để loại bỏ cruft và chỉ nhận được tên loại
type('abc') // String
Tuy nhiên, nó sẽ trả về Object
cho tất cả các loại do người dùng xác định.
Tất cả những điều này phải chịu một vấn đề tiềm ẩn, và đó là câu hỏi về cách đối tượng trong câu hỏi được xây dựng. Dưới đây là các cách khác nhau để xây dựng các đối tượng và các giá trị mà các phương thức kiểm tra loại khác nhau sẽ trả về:
// using a named function:
function Foo() { this.a = 1; }
var obj = new Foo();
(obj instanceof Object); // true
(obj instanceof Foo); // true
(obj.constructor == Foo); // true
(obj.constructor.name == "Foo"); // true
// let's add some prototypical inheritance
function Bar() { this.b = 2; }
Foo.prototype = new Bar();
obj = new Foo();
(obj instanceof Object); // true
(obj instanceof Foo); // true
(obj.constructor == Foo); // false
(obj.constructor.name == "Foo"); // false
// using an anonymous function:
obj = new (function() { this.a = 1; })();
(obj instanceof Object); // true
(obj.constructor == obj.constructor); // true
(obj.constructor.name == ""); // true
// using an anonymous function assigned to a variable
var Foo = function() { this.a = 1; };
obj = new Foo();
(obj instanceof Object); // true
(obj instanceof Foo); // true
(obj.constructor == Foo); // true
(obj.constructor.name == ""); // true
// using object literal syntax
obj = { foo : 1 };
(obj instanceof Object); // true
(obj.constructor == Object); // true
(obj.constructor.name == "Object"); // true
Mặc dù không phải tất cả các hoán vị đều có trong tập hợp các ví dụ này, hy vọng có đủ để cung cấp cho bạn ý tưởng về cách mọi thứ lộn xộn có thể nhận được tùy thuộc vào nhu cầu của bạn. Đừng giả sử bất cứ điều gì, nếu bạn không hiểu chính xác những gì bạn đang theo đuổi, bạn có thể sẽ bị phá mã, nơi bạn không mong đợi điều đó vì thiếu suy nghĩ về sự tinh tế.
Thảo luận về typeof
toán tử có thể là một thiếu sót rõ ràng, nhưng nó thực sự không hữu ích trong việc giúp xác định xem một loại có phải object
là một loại nhất định hay không, vì nó rất đơn giản. Hiểu nơi nào typeof
hữu ích là điều quan trọng, nhưng hiện tại tôi không cảm thấy rằng nó có liên quan khủng khiếp đến cuộc thảo luận này. Tâm trí của tôi là mở để thay đổi mặc dù. :)
constructor
phương thức của đối tượng (có .toString()
hoặc .name
) sẽ không hoạt động nếu Javascript của bạn đã được thu nhỏ bằng một công cụ như uglify hoặc đường dẫn tài sản Rails. Việc thu nhỏ đổi tên hàm tạo, vì vậy bạn sẽ kết thúc với tên lớp không chính xác như thế nào n
. Nếu bạn đang ở trong kịch bản này, bạn có thể chỉ muốn xác định thủ công một thuộc className
tính trên các đối tượng của mình và sử dụng thay thế đó.
Câu trả lời của Jason Bunting đã cho tôi đủ manh mối để tìm ra thứ tôi cần:
<<Object instance>>.constructor.name
Vì vậy, ví dụ, trong đoạn mã sau:
function MyObject() {}
var myInstance = new MyObject();
myInstance.constructor.name
sẽ quay trở lại "MyObject"
.
function getType(o) { return o && o.constructor && o.constructor.name }
Một mẹo nhỏ tôi sử dụng:
function Square(){
this.className = "Square";
this.corners = 4;
}
var MySquare = new Square();
console.log(MySquare.className); // "Square"
class Square
, tên là Square.name
/ MySquare.constructor.name
chứ không phải Square.prototype.name
; bằng cách đưa name
vào hàm xây dựng, nó không gây ô nhiễm nguyên mẫu hoặc bất kỳ trường hợp nào, nhưng có thể truy cập được từ một trong hai.
Nói chính xác, tôi nghĩ OP đã yêu cầu một hàm lấy tên hàm tạo cho một đối tượng cụ thể. Về mặt Javascript, object
không có một loại mà là một loại và bản thân nó . Tuy nhiên, các đối tượng khác nhau có thể có các nhà xây dựng khác nhau .
Object.prototype.getConstructorName = function () {
var str = (this.prototype ? this.prototype.constructor : this.constructor).toString();
var cname = str.match(/function\s(\w*)/)[1];
var aliases = ["", "anonymous", "Anonymous"];
return aliases.indexOf(cname) > -1 ? "Function" : cname;
}
new Array().getConstructorName(); // returns "Array"
(function () {})().getConstructorName(); // returns "Function"
Lưu ý: ví dụ dưới đây không được dùng nữa.
Một bài đăng trên blog được liên kết bởi Christian Sciberras chứa một ví dụ hay về cách thực hiện. Cụ thể, bằng cách mở rộng nguyên mẫu Object:
if (!Object.prototype.getClassName) {
Object.prototype.getClassName = function () {
return Object.prototype.toString.call(this).match(/^\[object\s(.*)\]$/)[1];
}
}
var test = [1,2,3,4,5];
alert(test.getClassName()); // returns Array
test.getClassName()
vs getClassName.apply(test)
.
Sử dụng Object.prototype.toString
Hóa ra, vì chi tiết bài đăng này, bạn có thể sử dụng Object.prototype.toString - mức độ thấp và triển khai chung của toString - để lấy loại cho tất cả các loại tích hợp
Object.prototype.toString.call('abc') // [object String]
Object.prototype.toString.call(/abc/) // [object RegExp]
Object.prototype.toString.call([1,2,3]) // [object Array]
Người ta có thể viết một hàm trợ giúp ngắn như
function type(obj){
return Object.prototype.toString.call(obj]).match(/\s\w+/)[0].trim()
}
return [object String] as String
return [object Number] as Number
return [object Object] as Object
return [object Undefined] as Undefined
return [object Function] as Function
.slice()
:Object.prototype.toString.call(obj).slice( 8, -1 );
Đây là một giải pháp mà tôi đã đưa ra để giải quyết những thiếu sót của thể hiện. Nó có thể kiểm tra các loại đối tượng từ các cửa sổ chéo và khung chéo và không gặp vấn đề với các kiểu nguyên thủy.
function getType(o) {
return Object.prototype.toString.call(o).match(/^\[object\s(.*)\]$/)[1];
}
function isInstance(obj, type) {
var ret = false,
isTypeAString = getType(type) == "String",
functionConstructor, i, l, typeArray, context;
if (!isTypeAString && getType(type) != "Function") {
throw new TypeError("type argument must be a string or function");
}
if (obj !== undefined && obj !== null && obj.constructor) {
//get the Function constructor
functionConstructor = obj.constructor;
while (functionConstructor != functionConstructor.constructor) {
functionConstructor = functionConstructor.constructor;
}
//get the object's window
context = functionConstructor == Function ? self : functionConstructor("return window")();
//get the constructor for the type
if (isTypeAString) {
//type is a string so we'll build the context (window.Array or window.some.Type)
for (typeArray = type.split("."), i = 0, l = typeArray.length; i < l && context; i++) {
context = context[typeArray[i]];
}
} else {
//type is a function so execute the function passing in the object's window
//the return should be a constructor
context = type(context);
}
//check if the object is an instance of the constructor
if (context) {
ret = obj instanceof context;
if (!ret && (type == "Number" || type == "String" || type == "Boolean")) {
ret = obj.constructor == context
}
}
}
return ret;
}
isInstance yêu cầu hai tham số: một đối tượng và một loại. Bí quyết thực sự về cách thức hoạt động của nó là kiểm tra xem đối tượng có ở cùng một cửa sổ không và nếu không có cửa sổ của đối tượng.
Ví dụ:
isInstance([], "Array"); //true
isInstance("some string", "String"); //true
isInstance(new Object(), "Object"); //true
function Animal() {}
function Dog() {}
Dog.prototype = new Animal();
isInstance(new Dog(), "Dog"); //true
isInstance(new Dog(), "Animal"); //true
isInstance(new Dog(), "Object"); //true
isInstance(new Animal(), "Dog"); //false
Đối số kiểu cũng có thể là hàm gọi lại trả về hàm tạo. Hàm gọi lại sẽ nhận được một tham số là cửa sổ của đối tượng được cung cấp.
Ví dụ:
//"Arguments" type check
var args = (function() {
return arguments;
}());
isInstance(args, function(w) {
return w.Function("return arguments.constructor")();
}); //true
//"NodeList" type check
var nl = document.getElementsByTagName("*");
isInstance(nl, function(w) {
return w.document.getElementsByTagName("bs").constructor;
}); //true
Một lưu ý là IE <9 không cung cấp hàm tạo trên tất cả các đối tượng nên thử nghiệm trên cho NodeList sẽ trả về false và cũng là isInstance (cảnh báo, "Hàm") sẽ trả về false.
Tôi đã thực sự tìm kiếm một điều tương tự và đã gặp câu hỏi này. Đây là cách tôi có được các loại: jsfiddle
var TypeOf = function ( thing ) {
var typeOfThing = typeof thing;
if ( 'object' === typeOfThing ) {
typeOfThing = Object.prototype.toString.call( thing );
if ( '[object Object]' === typeOfThing ) {
if ( thing.constructor.name ) {
return thing.constructor.name;
}
else if ( '[' === thing.constructor.toString().charAt(0) ) {
typeOfThing = typeOfThing.substring( 8,typeOfThing.length - 1 );
}
else {
typeOfThing = thing.constructor.toString().match( /function\s*(\w+)/ );
if ( typeOfThing ) {
return typeOfThing[1];
}
else {
return 'Function';
}
}
}
else {
typeOfThing = typeOfThing.substring( 8,typeOfThing.length - 1 );
}
}
return typeOfThing.charAt(0).toUpperCase() + typeOfThing.slice(1);
}
Bạn nên sử dụng somevar.constructor.name
như một:
const getVariableType = a => a.constructor.name.toLowerCase();
const d = new Date();
const res1 = getVariableType(d); // 'date'
const num = 5;
const res2 = getVariableType(num); // 'number'
const fn = () => {};
const res3 = getVariableType(fn); // 'function'
console.log(res1); // 'date'
console.log(res2); // 'number'
console.log(res3); // 'function'
Hàm kind () từ Agave.JS sẽ trả về:
Nó hoạt động trên tất cả các đối tượng và nguyên thủy của JS, bất kể chúng được tạo như thế nào và không có bất kỳ sự ngạc nhiên nào. Ví dụ:
kind(37) === 'Number'
kind(3.14) === 'Number'
kind(Math.LN2) === 'Number'
kind(Infinity) === 'Number'
kind(Number(1)) === 'Number'
kind(new Number(1)) === 'Number'
kind(NaN) === 'NaN'
kind('') === 'String'
kind('bla') === 'String'
kind(String("abc")) === 'String'
kind(new String("abc")) === 'String'
kind(true) === 'Boolean'
kind(false) === 'Boolean'
kind(new Boolean(true)) === 'Boolean'
kind([1, 2, 4]) === 'Array'
kind(new Array(1, 2, 3)) === 'Array'
kind({a:1}) === 'Object'
kind(new Object()) === 'Object'
kind(new Date()) === 'Date'
kind(function(){}) === 'Function'
kind(new Function("console.log(arguments)")) === 'Function'
kind(Math.sin) === 'Function'
kind(undefined) === 'undefined'
kind(null) === 'null'
Bạn có thể sử dụng instanceof
toán tử để xem nếu một đối tượng là một thể hiện của một đối tượng khác, nhưng vì không có lớp nào, bạn không thể có được một tên lớp.
instanceof
chỉ kiểm tra xem một đối tượng có kế thừa từ các đối tượng khác hay không. Ví dụ, một []
kế thừa đơn giản từ Array, nhưng Array cũng thừa hưởng từ Object. Vì hầu hết các đối tượng có nhiều cấp độ kế thừa, việc tìm ra nguyên mẫu gần nhất là một kỹ thuật tốt hơn. Xem câu trả lời của tôi để làm thế nào.
Đây là một triển khai dựa trên câu trả lời được chấp nhận :
/**
* Returns the name of an object's type.
*
* If the input is undefined, returns "Undefined".
* If the input is null, returns "Null".
* If the input is a boolean, returns "Boolean".
* If the input is a number, returns "Number".
* If the input is a string, returns "String".
* If the input is a named function or a class constructor, returns "Function".
* If the input is an anonymous function, returns "AnonymousFunction".
* If the input is an arrow function, returns "ArrowFunction".
* If the input is a class instance, returns "Object".
*
* @param {Object} object an object
* @return {String} the name of the object's class
* @see <a href="https://stackoverflow.com/a/332429/14731">https://stackoverflow.com/a/332429/14731</a>
* @see getFunctionName
* @see getObjectClass
*/
function getTypeName(object)
{
const objectToString = Object.prototype.toString.call(object).slice(8, -1);
if (objectToString === "Function")
{
const instanceToString = object.toString();
if (instanceToString.indexOf(" => ") != -1)
return "ArrowFunction";
const getFunctionName = /^function ([^(]+)\(/;
const match = instanceToString.match(getFunctionName);
if (match === null)
return "AnonymousFunction";
return "Function";
}
// Built-in types (e.g. String) or class instances
return objectToString;
};
/**
* Returns the name of a function.
*
* If the input is an anonymous function, returns "".
* If the input is an arrow function, returns "=>".
*
* @param {Function} fn a function
* @return {String} the name of the function
* @throws {TypeError} if {@code fn} is not a function
* @see getTypeName
*/
function getFunctionName(fn)
{
try
{
const instanceToString = fn.toString();
if (instanceToString.indexOf(" => ") != -1)
return "=>";
const getFunctionName = /^function ([^(]+)\(/;
const match = instanceToString.match(getFunctionName);
if (match === null)
{
const objectToString = Object.prototype.toString.call(fn).slice(8, -1);
if (objectToString === "Function")
return "";
throw TypeError("object must be a Function.\n" +
"Actual: " + getTypeName(fn));
}
return match[1];
}
catch (e)
{
throw TypeError("object must be a Function.\n" +
"Actual: " + getTypeName(fn));
}
};
/**
* @param {Object} object an object
* @return {String} the name of the object's class
* @throws {TypeError} if {@code object} is not an Object
* @see getTypeName
*/
function getObjectClass(object)
{
const getFunctionName = /^function ([^(]+)\(/;
const result = object.constructor.toString().match(getFunctionName)[1];
if (result === "Function")
{
throw TypeError("object must be an Object.\n" +
"Actual: " + getTypeName(object));
}
return result;
};
function UserFunction()
{
}
function UserClass()
{
}
let anonymousFunction = function()
{
};
let arrowFunction = i => i + 1;
console.log("getTypeName(undefined): " + getTypeName(undefined));
console.log("getTypeName(null): " + getTypeName(null));
console.log("getTypeName(true): " + getTypeName(true));
console.log("getTypeName(5): " + getTypeName(5));
console.log("getTypeName(\"text\"): " + getTypeName("text"));
console.log("getTypeName(userFunction): " + getTypeName(UserFunction));
console.log("getFunctionName(userFunction): " + getFunctionName(UserFunction));
console.log("getTypeName(anonymousFunction): " + getTypeName(anonymousFunction));
console.log("getFunctionName(anonymousFunction): " + getFunctionName(anonymousFunction));
console.log("getTypeName(arrowFunction): " + getTypeName(arrowFunction));
console.log("getFunctionName(arrowFunction): " + getFunctionName(arrowFunction));
//console.log("getFunctionName(userClass): " + getFunctionName(new UserClass()));
console.log("getTypeName(userClass): " + getTypeName(new UserClass()));
console.log("getObjectClass(userClass): " + getObjectClass(new UserClass()));
//console.log("getObjectClass(userFunction): " + getObjectClass(UserFunction));
//console.log("getObjectClass(userFunction): " + getObjectClass(anonymousFunction));
//console.log("getObjectClass(arrowFunction): " + getObjectClass(arrowFunction));
console.log("getTypeName(nativeObject): " + getTypeName(navigator.mediaDevices.getUserMedia));
console.log("getFunctionName(nativeObject): " + getFunctionName(navigator.mediaDevices.getUserMedia));
Chúng tôi chỉ sử dụng thuộc tính constructor khi chúng tôi không có lựa chọn nào khác.
Bạn có thể sử dụng toán tử "instanceof" để xác định xem một đối tượng có phải là một thể hiện của một lớp nhất định hay không. Nếu bạn không biết tên của loại đối tượng, bạn có thể sử dụng thuộc tính hàm tạo của nó. Thuộc tính constructor của các đối tượng, là một tham chiếu đến hàm được sử dụng để khởi tạo chúng. Thí dụ:
function Circle (x,y,radius) {
this._x = x;
this._y = y;
this._radius = raduius;
}
var c1 = new Circle(10,20,5);
Bây giờ c1.constructor là một tham chiếu đến Circle()
hàm. Bạn có thể sử dụng typeof
toán tử, nhưng typeof
toán tử hiển thị thông tin hạn chế. Một giải pháp là sử dụng toString()
phương thức của đối tượng toàn cầu Object. Ví dụ: nếu bạn có một đối tượng, giả sử myObject, bạn có thể sử dụng toString()
phương thức của Đối tượng toàn cầu để xác định loại lớp của myObject. Dùng cái này:
Object.prototype.toString.apply(myObject);
Nói rằng bạn có var obj;
Nếu bạn chỉ muốn tên của loại obj, như "Đối tượng", "Mảng" hoặc "Chuỗi", bạn có thể sử dụng tên này:
Object.prototype.toString.call(obj).split(' ')[1].replace(']', '');
Gần nhất bạn có thể nhận được typeof
, nhưng nó chỉ trả về "đối tượng" cho bất kỳ loại tùy chỉnh nào. Đối với những người, xem Jason Bunting .
Chỉnh sửa, Jason đã xóa bài đăng của mình vì một số lý do, vì vậy chỉ cần sử dụng constructor
tài sản của Object .
Nếu bất cứ ai đang tìm kiếm một giải pháp đang hoạt động với jQuery, thì đây là mã wiki được điều chỉnh (bản gốc phá vỡ jQuery).
Object.defineProperty(Object.prototype, "getClassName", {
value: function() {
var funcNameRegex = /function (.{1,})\(/;
var results = (funcNameRegex).exec((this).constructor.toString());
return (results && results.length > 1) ? results[1] : "";
}
});
getName
và rơi xuống.
Lodash có nhiều isMethods vì vậy nếu bạn đang sử dụng Lodash, có thể một mixin như thế này có thể hữu ích:
// Mixin for identifying a Javascript Object
_.mixin({
'identify' : function(object) {
var output;
var isMethods = ['isArguments', 'isArray', 'isArguments', 'isBoolean', 'isDate', 'isArguments',
'isElement', 'isError', 'isFunction', 'isNaN', 'isNull', 'isNumber',
'isPlainObject', 'isRegExp', 'isString', 'isTypedArray', 'isUndefined', 'isEmpty', 'isObject']
this.each(isMethods, function (method) {
if (this[method](object)) {
output = method;
return false;
}
}.bind(this));
return output;
}
});
Nó thêm một phương thức vào lodash gọi là "xác định" hoạt động như sau:
console.log(_.identify('hello friend')); // isString
Ok, mọi người, tôi đã dần dần xây dựng một phương pháp bắt tất cả cho việc này trong vài năm qua lol! Bí quyết là:
Để biết ví dụ (hoặc để xem cách tôi xử lý vấn đề), hãy xem đoạn mã sau trên github: https://github.com/elycruz/sjljs/blob/master/src/sjl/sjl.js và tìm kiếm:
classOf =
,
classOfIs =
và hoặc
defineSubClass =
(không có backticks (`)).
Như bạn có thể thấy tôi có một số cơ chế bắt buộc classOf
phải luôn cung cấp cho tôi tên loại lớp / hàm tạo bất kể đó là lớp nguyên thủy, lớp do người dùng định nghĩa, giá trị được tạo bằng hàm tạo gốc, Null, NaN, v.v. Đối với mỗi giá trị javascript duy nhất tôi sẽ nhận được tên loại duy nhất từ classOf
hàm. Ngoài ra, tôi có thể chuyển các hàm tạo thực tế vàosjl.classOfIs
để kiểm tra loại giá trị ngoài việc có thể chuyển cả tên loại của nó! Ví dụ:
`` `// Xin vui lòng tha thứ cho không gian tên dài! Tôi không có ý tưởng về tác động cho đến khi sử dụng chúng một thời gian (họ hút haha)
var SomeCustomClass = sjl.package.stdlib.Extendable.extend({
constructor: function SomeCustomClass () {},
// ...
}),
HelloIterator = sjl.ns.stdlib.Iterator.extend(
function HelloIterator () {},
{ /* ... methods here ... */ },
{ /* ... static props/methods here ... */ }
),
helloIt = new HelloIterator();
sjl.classOfIs(new SomeCustomClass(), SomeCustomClass) === true; // `true`
sjl.classOfIs(helloIt, HelloIterator) === true; // `true`
var someString = 'helloworld';
sjl.classOfIs(someString, String) === true; // `true`
sjl.classOfIs(99, Number) === true; // true
sjl.classOf(NaN) === 'NaN'; // true
sjl.classOf(new Map()) === 'Map';
sjl.classOf(new Set()) === 'Set';
sjl.classOfIs([1, 2, 4], Array) === true; // `true`
// etc..
// Also optionally the type you want to check against could be the type's name
sjl.classOfIs(['a', 'b', 'c'], 'Array') === true; // `true`!
sjl.classOfIs(helloIt, 'HelloIterator') === true; // `true`!
`` `
Nếu bạn muốn đọc thêm về cách tôi sử dụng thiết lập được đề cập ở trên, hãy xem repo: https://github.com/elycruz/sjljs
Ngoài ra các cuốn sách có nội dung về chủ đề: - "Các mẫu JavaScript" của Stoyan Stefanov. - "Javascript - Hướng dẫn dứt khoát." của David Flanagan. - và nhiều người khác .. (tìm kiếm trang web).
Ngoài ra, bạn có thể nhanh chóng kiểm tra các tính năng tôi đang nói ở đây: - http://sjljs.elycruz.com/0.5.18/tests/for-browser/ (cũng là đường dẫn 0,5,18 trong url có các nguồn từ github trên đó trừ đi node_modules và như vậy).
Chúc mừng mã hóa!
function getType(entity){
var x = Object.prototype.toString.call(entity)
return x.split(" ")[1].split(']')[0].toLowerCase()
}
function checkType(entity, type){
return getType(entity) === type
}