>  기사  >  웹 프론트엔드  >  Javascript_javascript 기술의 유형 판단에 대해 간략하게 이야기

Javascript_javascript 기술의 유형 판단에 대해 간략하게 이야기

WBOY
WBOY원래의
2016-05-16 15:36:051123검색

데이터 유형을 결정하는 방법에는 여러 가지가 있습니다

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

Dojo 상속 메커니즘에서 instanceof 적용

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
참고: js에는 정의되지 않음 및 Null의 전역 유형이 없고 숫자, 문자열 및 부울은 해당 유형을 감지할 수 없기 때문에 정의되지 않음 및 null이 개체 유형으로 감지됩니다.

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,
  /(&#63;:)/,
  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") );
정의되지 않음과 null을 제외한 다른 유형의 변수 유형은 생성자를 사용하여 결정할 수 있습니다

4. 범용 Object.prototype.toString.call

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
부착된 판단 기능은 자바스크립트의 데이터 유형에 대해 얼마나 알고 계시나요?

5. jquery 구현: "1.8.2",

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 &#63; 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
},
Object.prototype.toString.call을 사용하여 jquery를 구현한 것을 볼 수 있습니다
성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.