이 글의 내용은 JavaScript 데이터 유형 및 변수 분석에 관한 것입니다(예제 포함). 참고할 만한 가치가 있으니 도움이 필요한 분들에게 도움이 되길 바랍니다.
이 글에서는 JS의 데이터 유형 및 변수에 대해 이야기하겠습니다. JS를 배울 때 가장 기본적인 질문이지만 중요한 질문입니다. 제 공유가 여러분에게 도움이 되기를 바랍니다.
기사 시작 부분에서 인터뷰에서 만난 몇 가지 질문을 먼저 언급하겠습니다.
예:
값에 따른 매개변수 전달을 이해하는 방법은 무엇입니까?
일시적 데드존이란 무엇인가요?
변수홍보란?
전역 변수와 창 속성의 차이점은 무엇인가요? 왜?
... ...
이 글의 스타일은 제가 경험한 면접 질문 몇 가지를 삽입하면서 지식 포인트를 분석하는 것입니다.
JS에는 숫자값, 문자열, 부울값, null, 정의되지 않음, 기호의 6가지 기본 데이터 유형이 있습니다.
기본 데이터 유형의 경우 우리가 이해해야 할 것은 기본 유형이 메모리에 저장되는 방식이 스택이라는 것입니다. 각 값은 별도로 저장되며 서로 영향을 미치지 않습니다.
기본 유형은 값으로 액세스됩니다. 비교할 때는 값으로 비교하세요:
1 === 1 // true
참조 유형의 값은 힙에 저장되고 참조는 스택에 저장됩니다.
참조 유형은 참조로 액세스됩니다. 비교할 때 참조도 비교하세요.
{} === {} // => false
JS에서 매개변수는 모든 유형의 값, 심지어 함수일 수 있습니다.
여기서 분석해야 할 것은 어떤 유형의 매개변수가 전달되는지 입니다. 참조 유형 또는 기본 유형?
먼저 기본 예제를 살펴보겠습니다.
var out_num = 1; function addOne(in_num) { in_num += 1; return in_num; } addOne(out_num); // => 2 out_num // => 1
이 예제에서는 addOne() 함수에 실제 매개변수 out_num을 전달합니다. 이때 out_num은 in_num에 전달됩니다. 즉, 내부 in_num = out_num 프로세스. 우리가 보는 최종 결과는 out_num이 함수에 의해 변경되지 않았다는 것입니다. 이는 in_num과 out_num이 메모리에 독립적으로 저장된 두 개의 값, 즉 값으로 전달되었음을 나타냅니다. in_num = out_num
的过程。最后我们看到的结果是 out_num 并没有被函数改变,说明 in_num 和 out_num 是两个在内存中独立存放的值,即按值传递。
再来看一个变形:
var out_obj = { value: 1 }; function addOne(in_obj) { in_obj.value += 1; return in_obj; } addOne(out_obj); // => { value: 2 } out_obj // => { value: 2 }
问题来了?函数参数不是按值传递吗?为什么这里函数内部的处理反映到外部了?这是一个超级超级超级的理解误区。
首先,我们还是得摆正观点,即函数参数是按值传递的。那这里怎么理解呢?对于引用类型而言,前面说引用类型分为引用和实际的内存空间。在这里 out_obj 依旧传递给 in_obj,即 in_obj = out_obj
,out_obj 和 in_obj 是两个引用,它们在内存中的存储方式是独立的,但是它们却指向同一块内存。
而 in_obj.value = 1
var out_obj = { value: 1 }; function addOne(in_obj) { in_obj = { value: 2 }; return in_obj; } addOne(out_obj); // => { value: 2 } out_obj // => { value: 1 }
우선 우리의 관점을 바로잡아야 합니다. 즉, 함수 매개변수가 값으로 전달된다는 것입니다.
그럼 여기서는 무엇을 이해하시나요? 참조 유형의 경우 참조 유형은 참조와 실제 메모리 공간으로 구분된다고 앞서 말했습니다. 여기서 out_obj는 여전히 in_obj로 전달됩니다. 즉,in_obj = out_obj
입니다. out_obj와 in_obj는 독립적으로 메모리에 저장되지만 동일한 메모리를 가리킵니다.
그리고in_obj.value = 1
은 직접 연산의 실제 객체입니다. 실제 개체에 대한 변경 사항은 실제 개체를 참조하는 모든 참조에 동기화됩니다.
이 예를 다시 보면 더 명확해질 수 있습니다.
typeof null // => 'object' typeof [] // => 'object'
데이터 유형을 결정하는 데에는 일반적으로 세 가지 특정 방법이 있습니다.
1. typeof 연산자
typeof 연산자는 데이터 유형을 나타내는 문자열을 반환합니다. 다음과 같은 명백한 결함이 있습니다.{} instanceof Object // => true [] instanceof Array // => true [] instanceof Object // => true
2.instanceof 연산자
typeof는type 태그
를 판단하여 데이터 유형을 판단하는 반면, instanceof는 생성자의 프로토타입이 객체 프로토타입 체인의 어느 곳에나 나타나는지 여부를 판단합니다. 예:function Car(make, model, year) { this.make = make; this.model = model; this.year = year; } var auto = new Car('Honda', 'Accord', 1998); console.log(auto instanceof Car); // => true console.log(auto instanceof Object); // => true
1 instanceof Number // => false Number(1) instanceof Number // => false new Number(1) instanceof Number // => true
Object.prototype.toString.call(JSON) // => "[object JSON]"
3.
🎜🎜 이는 현재 가장 권장되는 방법으로 JSON, 일반, 날짜, 오류 등 모든 데이터 유형을 보다 정확하고 정확하게 확인할 수 있습니다. Lodash에서 데이터 유형을 결정하는 핵심은 Object.prototype.toString() 메서드이기도 합니다. 🎜if (isTrue) { // ... } else {}
你先要知道 JS 中类数组对象是什么样子的,并寻求一个实际的参照物,比如 arguments 就是类数组对象。那么类数组对象具有的特点是:真值 & 对象 & 具有 length 属性 & length 为整数 & length 的范围大于等于 0,小于等于最大安全正整数(Number.MAX_SAFE_INTEGER)。
在你分析特点的时候,答案就呼之欲出了。【注意全面性】
JS 数据类型的动态性将贯穿整个 JS 的学习,这是 JS 非常重要的特性,很多现象就是因为动态性的存在而成为 JS 独有。
正是由于动态性,JS 的数据类型可能在你毫无察觉的情况下,就发生了改变,直到运行时报错。
这里主要分析下面 8 种转换规则。
1、if 语句
if 语句中的类型转换是最常见的。
if (isTrue) { // ... } else {}
在 if 语句中,会自动调用 Boolean() 转型函数对变量 isTrue 进行转换。
当 isTrue 的值是 null, undefined, 0, NaN, '' 时,都会转为 false。其余值除 false 本身外都会转为 true。
2、Number() 转型函数
我们重点关注 null undefined 以及字符串在 Number() 下的转换:
Number(null) // => 0 Number(undefined) // => NaN Number('') // => 0 Number('123') // => 123 Number('123abc') // => NaN
注意和 parseInt() 对比。
3、parseInt()
parseInt(null) // => NaN parseInt(undefined) // => NaN parseInt('') // => NaN parseInt('123') // => 123 parseInt('123abc') // => 123
4、==
这里需要注意的是:
null == undefined // => true null == 0 // => false undefined == false // => false
null 与 undefined 的相等性是由 ECMA-262 规定的,并且 null 与 undefined 在比较相等性时不能转换为其他任何值。
5、关系操作符
对于两个字符串的比较,是比较的字符编码值:
'B' true
一个数值,另一个其他类型,都将转为数字进行比较。
两个布尔值转为数值进行比较。
对象,先调用 valueOf(),若不存在该方法,则调用 toString()。
6、加法
加法中特别注意的是,数字和字符串相加,将数字转为字符串。
'1' + 2 => // '12' 1 + 2 => // 3
对于对象和布尔值,调用它们的 toString() 方法得到对应的字符串值,然后进行字符串相加。对于 undefined 和 null 调用 String() 取得字符串 'undeifned' 和 'null'。
{ value: 1 } + true // => "[object Object]true"
7、减法
对于字符串、布尔值、null 或者 undefined,自动调用 Number(),转换结果若为 NaN,那么最终结果为 NaN。
对于对象,先调用 valueOf(),如果得到 NaN,结果为 NaN。如果没有 valueOf(),则调用 toString()。
8、乘法、除法
对于非数值,都会调用 Number() 转型函数。
JS 中有三种声明变量的方式:var, let, const。
var 声明变量最大的一个特点是存在变量提升。
console.log(a); // undefined var a = 1; console.log(a); // 1
第一个打印结果表示,在声明变量 a 之前,a 就已经可以访问了,只不过并未赋值。这就是变量提升现象。(具体原因,我放在后面分析作用域的时候来写)
let 和 const 就不存在这个问题,但是又引入了暂时性死区这样的概念。
/** * 这上面都属于变量 a 的暂时性死区 * console.log(a) // => Reference Error */ let a = 1; console.log(a); // => 1
即声明 a 之前,不能够访问 a,而直接报错。
而暂时性死区的出现又引出另外一个问题,即 typeof 不再安全。你可以参考这篇文章 http://es-discourse.com/t/why...
补充:一个经典面试题
for (var i = 0; i <p>我先不再这里展开分析,我打算放到异步与事件循环机制中去分析。不过这里将 var 替换成 let 可以作为一种解决方案。如果你有兴趣,也可以先去分析。</p><p>对于 const,这里再补充一点,用于加深对基本类型和引用类型的理解。</p><pre class="brush:php;toolbar:false">const a = 1; const b = { value: 1 }; a = 2; // => Error b.value = 2; // => 2 b = { value: 2 }; // => Error
本质上,const 并不是保证变量的值不得改动,而是变量指向的内存地址不得改动。
直接通过 var 声明全局变量,这个全局变量会作为 window 对象的一个属性。
var a = 1; window.a // => 1
在这里提出两个问题,一是 let 声明的全局变量会成为 window 的属性吗?二是 var 声明的全局变量和直接在 window 创建属性有没有区别?
先来回答第一问题。let 声明的全局变量不会成为 window 的属性。用什么来支撑这样的结论呢?在 ES6 中,对于 let 和 const 声明的变量从一开始就形成封闭作用域。想想之前的暂时性死区。
第二个问题,var 声明的全局变量和直接在 window 创建属性存在着本质的区别。先看下面的代码:
var a = 1; window.a // => 1 window.b = 2; delete window.a delete window.b window.a // => 1 window.b // => undefined
我们可以看到,直接创建在 window 上的属性可以被 delete 删除,而 var 创建的全局属性则不会。这是现象,通过现象看本质,二者本质上的区别在于:
var를 사용하여 선언한 전역 변수의 [[configurable]] 데이터 속성 값이 false이므로 삭제로 삭제할 수 없습니다. 객체에 직접 생성된 속성에 대한 [[configurable]]의 기본값은 true입니다. 즉, 삭제를 통해 삭제할 수 있습니다. ([[configurable]] 속성에 대해서는 이후 글에서 객체 분석 시 언급하겠습니다)
이 "데이터 유형 및 변수"글에서는 7가지 주요 범주가 분석됩니다. 검토해 보겠습니다:
기본 유형, 참조 유형, 매개변수 전송 방법, 데이터 유형 결정 방법, 데이터 유형 변환 방법, 변수 승격 및 임시 데드존, 전역 변수 선언.
학교채용 면접에서 많이 나오는 시험 포인트일 뿐만 아니라, JS를 배우기 위한 필수 지식 포인트이기도 합니다.
Tip1: "자바스크립트 고급 프로그래밍"이라는 책을 "프론트엔드 바이블"이라고 부르는 이유가 있습니다. 캠퍼스 리크루팅을 준비하는 당신에게 꼭 필요한 내용입니다! 책을 백 번 읽으면 그 의미가 분명해질 것입니다. 인터뷰에서 접하게 되는 JS 관련 지식 포인트는 대부분 이 책에서 만나보실 수 있습니다!
Tip2: 리뷰를 준비하는 과정에서 지식의 모듈성과 상관성에 주의하세요. 오늘날의 "데이터 유형 및 변수" 모듈과 같은 지식 모듈을 스스로 분할할 수 있는 능력이 있어야 합니다. 관련성은 모든 지식이 관련되어 있음을 의미합니다. 예를 들어 범위 및 메모리와 같은 모듈이 포함됩니다.
위 내용은 JavaScript 데이터 유형 및 변수 분석(예제 포함)의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!