데이터 유형을 결정하는 방법에는 여러 가지가 있습니다
1. 단항 연산자 유형
2. 관계 연산자 인스턴스
3. 생성자 속성
4. 프로토타입 속성
1. 유형
typeof의 반환 값은 다음과 같습니다
유형 | 구조 |
---|---|
정의되지 않음 | "undefined" |
무효 |
"object" (아래 참조) |
부울 값 | "boolean" |
가치 | "number" |
문자열 | "string" |
기호(ECMAScript 6의 새로운 기능) | "symbol" |
호스트 객체(브라우저 등 JS 환경에서 제공) | 구현에 따라 다름 |
함수 객체(ECMA-262 용어로 [[Call]] 구현) | "function" |
기타 개체 | "object" |
간단하고 투박한 방법, 코드만 보면
// 以下代码在版本 Google Chrome 45.0.2454.101 m 中测试通过 // Numbers console.log(typeof 37 === 'number'); console.log(typeof 3.14 === 'number'); console.log(typeof Math.LN2 === 'number'); console.log(typeof Infinity === 'number'); console.log(typeof NaN === 'number'); // 尽管NaN是"Not-A-Number"的缩写,意思是"不是一个数字" console.log(typeof Number(1) === 'number'); // 不要这样使用! // Strings console.log(typeof "" === 'string'); console.log(typeof "bla" === 'string'); console.log(typeof (typeof 1) === 'string'); // console.log(typeof返回的肯定是一个字符串 console.log(typeof String("abc") === 'string'); // 不要这样使用! // Booleans console.log(typeof true === 'boolean'); console.log(typeof false === 'boolean'); console.log(typeof Boolean(true) === 'boolean'); // 不要这样使用! // Symbols console.log(typeof Symbol() === 'symbol'); console.log(typeof Symbol('foo') === 'symbol'); console.log(typeof Symbol.iterator === 'symbol'); // Undefined console.log(typeof undefined === 'undefined'); console.log(typeof blabla === 'undefined'); // 一个未定义的变量,或者一个定义了却未赋初值的变量 // Objects 使用Array.isArray或者Object.prototype.toString.call方法可以从基本的对象中区分出数组类型 console.log(typeof {a:1} === 'object'); console.log(typeof [1, 2, 4] === 'object'); console.log(typeof /^[a-zA-Z]{5,20}$/ === 'object'); console.log(typeof {name:'wenzi', age:25} === 'object'); console.log(typeof null === 'object');//true // 下面的容易令人迷惑,不要这样使用! console.log(typeof new Boolean(true) === 'object'); console.log(typeof new Number(1) === 'object'); console.log(typeof new Date() === 'object'); console.log(typeof new String("abc") === 'object'); console.log(typeof new Error() === 'object'); // 函数 console.log(typeof function(){} === 'function'); console.log(typeof Math.sin === 'function');
typeof는 위 7가지 유형만 확인할 수 있습니다
2.인스턴스
instanceof 연산자는 처리 중인 객체의 유형을 식별하는 데 사용되므로 개발자는 객체가 특정 유형인지 명시적으로 확인해야 합니다.
1.instanceof는 생성자와 아무 관련이 없습니다
var A = function() {}; A.prototype = {}; var B = {}; console.log(A.constructor);//function Function() { [native code] } console.log(B.constructor);//function Object() { [native code] } var a = new A(); A.prototype = {}; var b = new A(); b.constructor = A.constructor; console.log(a.constructor === A);//false console.log(a.constructor);//function Object() { [native code] } console.log(typeof A);//function Object() { [native code] } console.log(a.constructor === b.constructor);//false console.log(b.constructor);//function Function() { [native code] } console.log(a instanceof A);//false console.log(b instanceof A);//true
2. Instanceof는 관계 연산자라고도 하며, 특정 생성자의 프로토타입 속성이 감지할 다른 객체의 프로토타입 체인에 존재하는지 여부를 확인하는 데 사용할 수 있습니다.
var str = new String("hello world"); console.log(str instanceof String);//true console.log(String instanceof Function);//true console.log(str instanceof Function);//false
세 번째 출력이 false를 반환하는 이유는 무엇입니까? 원래 주소: Javascript의 instanceof에 대한 질문
//表达式一的指向 console.log(str.__proto__ === String.prototype);//true console.log(str instanceof String); //true //表达式二的指向 console.log(String .__proto__ === Function.prototype);//true console.log(String instanceof Function);//true //表达式三的指向 console.log(str .__proto__ === String.prototype);//true console.log(str .__proto__.__proto__ === String.prototype.__proto__);//true console.log(str .__proto__.__proto__ === Object.prototype);//true console.log(str .__proto__.__proto__.__proto__ === null);//true console.log(str instanceof Object);//true console.log(str instanceof Function);//false
또 다른 복잡한 사용법을 살펴보겠습니다
console.log(Object instanceof Object);//true console.log(Function instanceof Function);//true console.log(Number instanceof Number);//false console.log(String instanceof String);//false console.log(Function instanceof Object);//true console.log(Foo instanceof Function);//true console.log(Foo instanceof Foo);//false
왜, 왜 그럴까요? 다음의 의미를 이해해야 합니다
1. 이 연산자는 언어 사양에서 어떻게 정의되나요?
2. 자바스크립트 프로토타입 상속 메커니즘
Object의 객체 인스턴스
// 为了方便表述,首先区分左侧表达式和右侧表达式 ObjectL = Object, ObjectR = Object; console.log(ObjectL instanceof ObjectR);//true
// 下面根据规范逐步推演 console.log(ObjectL.__proto__ === Function.prototype); //true console.log(ObjectL.__proto__.__proto__ === Object.prototype);//true
함수의 함수 인스턴스
FunctionL = Function, FunctionR = Function; console.log(FunctionL instanceof FunctionR);//true console.log(FunctionL.__proto__ === Function.prototype); //true <strong>Foo instanceof Foo </strong> function Foo(){} var foo = new Foo(); FooL = Foo, FooR = Foo; console.log(FooL instanceof FooR);//false console.log(FooL.__proto__ === Function.prototype );//true console.log(FooL.__proto__.__proto__ === Object.prototype );//true console.log(FooL.__proto__.__proto__.__proto__ === null );//true
JavaScript에는 Java와 마찬가지로 다중 상속이라는 개념이 없습니다. 하지만 Dojo에서 선언을 사용하여 클래스를 선언하면 여러 클래스에서 상속할 수 있습니다
dojo.declare("Aoo",null,{}); dojo.declare("Boo",null,{}); dojo.declare("Foo",[Aoo,Boo],{}); var foo = new Foo(); console.log(foo instanceof Aoo);//true console.log(foo instanceof Boo);//false console.log(foo.isInstanceOf(Aoo));//true console.log(foo.isInstanceOf(Boo));//true
브라우저에서 스크립트는 여러 창 간에 상호 작용해야 할 수도 있습니다. 여러 창은 여러 전역 환경을 의미하며, 서로 다른 전역 환경에는 서로 다른 전역 개체가 있으므로 내장 유형 생성자가 다릅니다. 이로 인해 몇 가지 문제가 발생할 수 있습니다. 예를 들어 [] 인스턴스of window.frames[0].Array 표현식은 Array.prototype !== window.frames[0].Array.prototype이므로 false를 반환하므로 Array.isArray(myObj) 또는 Object를 사용해야 합니다. 프로토타입.toString.call(myObj) === "[object Array]" - myObj가 배열인지 확인합니다.
// 以下代码在版本 Google Chrome 45.0.2454.101 m 中测试通过 // Numbers console.log(37 instanceof Number);//false console.log( 3.14 instanceof Number);.//false console.log( Math.LN2 instanceof Number);//false console.log( Infinity instanceof Number);//false console.log( NaN instanceof Number); // false尽管NaN是"Not-A-Number"的缩写,意思是"不是一个数字" console.log( Number(1) instanceof Number); // false不要这样使用! // Strings console.log( "" instanceof String);// false console.log( "bla" instanceof String);// false console.log( ( 1) instanceof String); // falseconsole.log(返回的肯定是一个字符串 console.log( String("abc") instanceof String); // false 不要这样使用! // Booleans console.log( true instanceof Boolean);// false console.log( false instanceof Boolean);// false console.log( Boolean(true) instanceof Boolean); //false 不要这样使用! // Symbols console.log( Symbol() instanceof Symbol);// false console.log( Symbol("foo") instanceof Symbol);// false console.log( Symbol.iterator instanceof Symbol);// false // Undefined var blabla; //console.log( undefined instanceof Undefined);// Uncaught ReferenceError: Undefined is not defined //console.log( blabla instanceof Undefined); // Uncaught ReferenceError: Undefined is not defined console.log( undefined instanceof Object);// false console.log( blabla instanceof Object);// false // Objects 使用Array.isArray或者Object.prototype.toString.call方法可以从基本的对象中区分出数组类型 console.log( {a:1} instanceof Object);//true console.log( [1, 2, 4] instanceof Object);//true console.log( /^[a-zA-Z]{5,20}$/ instanceof Object);//true console.log( {name:'wenzi', age:25} instanceof Object);//true console.log( null === Object);//false // 下面的容易令人迷惑,不要这样使用! console.log( new Boolean(true) instanceof Object);//true console.log( new Number(1) instanceof Object);//true console.log( new Date() instanceof Object);//true console.log( new String("abc") instanceof Object);//true console.log( new Error() instanceof Object);//true // 函数 console.log( function(){} instanceof Function );//true console.log( Math.sin instanceof Function);//true
3. 생성자
instanceof를 사용하여 변수 유형을 감지하는 경우 숫자, '문자열' 및 bool 유형을 감지할 수 없습니다. 따라서 이 문제를 해결하기 위한 다른 방법을 찾아야 합니다Object.prototype.constructor는 객체의 프로토타입을 생성한 함수에 대한 참조를 반환합니다. 이 속성의 값은 함수 이름을 포함하는 문자열이 아니라 함수 자체입니다. 기본 값(예: 1, true 또는 "test")의 경우 이 속성은 읽기 전용이며 모든 개체는 프로토타입에서 생성자 속성을 상속합니다.
생성자는 원래 생성자를 가리키는 프로토타입 객체의 속성입니다. 그러나 인스턴스 객체가 속성을 검색하는 순서에 따라 인스턴스 객체에 인스턴스 속성이나 메소드가 없으면 프로토타입 체인에서 검색되므로 인스턴스 객체도 생성자 속성 <🎜을 사용할 수 있습니다. >
function Person(){ } var Tom = new Person(); console.log(Tom.constructor === Person);//true
function Person(){ } function Student(){ } Student.prototype = new Person(); var John = new Student(); console.log(John.constructor==Student); // false console.log(John.constructor==Person); // true
function Type() { }; var types = [ new Array, [], new Boolean, true, // remains unchanged new Date, new Error, new Function, function(){}, Math, new Number, 1, // remains unchanged new Object, {}, new RegExp, /(?:)/, new String, "test" // remains unchanged ]; for(var i = 0; i < types.length; i++) { types[i].constructor = Type; types[i] = [ types[i].constructor, types[i] instanceof Type, types[i].toString() ]; }; console.log( types.join("\n") );
toString() 메소드를 사용하여 객체 유형 감지
function Type() { }; var toString = Object.prototype.toString; console.log(toString.call(new Date) === '[object Date]');//true console.log(toString.call(new String) ==='[object String]');//true console.log(toString.call(new Function) ==='[object Function]');//true console.log(toString.call(Type) ==='[object Function]');//true console.log(toString.call('str') ==='[object String]');//true console.log(toString.call(Math) === '[object Math]');//true console.log(toString.call(true) ==='[object Boolean]');//true console.log(toString.call(/^[a-zA-Z]{5,20}$/) ==='[object RegExp]');//true console.log(toString.call({name:'wenzi', age:25}) ==='[object Object]');//true console.log(toString.call([1, 2, 3, 4]) ==='[object Array]');//true //Since JavaScript 1.8.5 console.log(toString.call(undefined) === '[object Undefined]');//true console.log(toString.call(null) === '[object Null]');//true
jquery는 $.type 인터페이스를 제공합니다. 코드를 살펴보세요
var m = Object.prototype.toString //501行 E = {};//512行 isFunction: function(a) { //645行 return p.type(a) === "function" }, isArray: Array.isArray || function(a) { return p.type(a) === "array" } , isWindow: function(a) { return a != null && a == a.window }, isNumeric: function(a) { return !isNaN(parseFloat(a)) && isFinite(a) }, type: function(a) { return a == null ? String(a) : E[m.call(a)] || "object" }, isPlainObject: function(a) { if (!a || p.type(a) !== "object" || a.nodeType || p.isWindow(a)) return !1; try { if (a.constructor && !n.call(a, "constructor") && !n.call(a.constructor.prototype, "isPrototypeOf")) return !1 } catch (c) { return !1 } var d; for (d in a) ; return d === b || n.call(a, d) }, isEmptyObject: function(a) { var b; for (b in a) return !1; return !0 },