Skip to content

Commit 57e5203

Browse files
committed
js数据基础
1 parent 406a6c8 commit 57e5203

File tree

1 file changed

+84
-61
lines changed

1 file changed

+84
-61
lines changed

_posts/2018-12-27-JS基础及常见面试考点一.md

Lines changed: 84 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -16,15 +16,15 @@ tag: js基础
1616
* 1种引用类型(对象):Object
1717

1818
**本地对象、内置对象和宿主对象:**
19-
ECMA-262 把本地对象(native object)定义为“独立于宿主环境的 ECMAScript 实现提供的对象”。常见的本地对象有 String、Boolean、Number、Object、Function、Array、Date、RegExp、Error、ReferenceError等。其实,本地对象就是es中定义的引用类型。
19+
  ECMA-262 把本地对象(native object)定义为“独立于宿主环境的 ECMAScript 实现提供的对象”。常见的本地对象有 String、Boolean、Number、Object、Function、Array、Date、RegExp、Error、ReferenceError等。其实,本地对象就是es中定义的引用类型。
2020

21-
ECMA-262 把内置对象(built-in object)定义为“由 ECMAScript 实现提供的、独立于宿主环境的所有对象,在 ECMAScript 程序开始执行时出现”。即内置对象是本地对象的子集,但是内置对象不是需要手动实例化,而是在在程序开始执行时已经被实例化了。如 Global、Math。在 ECMAScript 中,所有函数必须是某个对象的方法,比如parseInt 可以直接调用,事实上 parseInt 就是 Global 对象上的方法。调用 Math 对象上的方法不需要实例化,直接调用即可, Math.ceil()。
21+
  ECMA-262 把内置对象(built-in object)定义为“由 ECMAScript 实现提供的、独立于宿主环境的所有对象,在 ECMAScript 程序开始执行时出现”。即内置对象是本地对象的子集,但是内置对象不是需要手动实例化,而是在在程序开始执行时已经被实例化了。如 Global、Math。在 ECMAScript 中,所有函数必须是某个对象的方法,比如parseInt 可以直接调用,事实上 parseInt 就是 Global 对象上的方法。调用 Math 对象上的方法不需要实例化,直接调用即可, Math.ceil()。
2222

23-
宿主对象是指由宿主环境提供的对象,对于嵌入到网页中的 js 而言,浏览器就是其宿主环境,提供 BOM、DOM、console 等宿主对象。
23+
  宿主对象是指由宿主环境提供的对象,对于嵌入到网页中的 js 而言,浏览器就是其宿主环境,提供 BOM、DOM、console 等宿主对象。
2424
#### <font color="#65A5EA" size="3">2. 基本类型和对象的区别</font> {#say-goodbyte}
25-
基本类型没有自己的属性和方法。对象有自己的属性和方法。
26-
**但是,为什么有的基本类型也可以调用方法呢?比如 123.length**
27-
那是因为除了 null、undefined 以外的基本类型都有与之对应的特殊的引用类型——包装类型。当代码被解释执行时,底层会将基本类型转换成引用类型,这样基本类型就可以调用与之相对应的引用类型的属性和方法。
25+
&emsp;&emsp;基本类型没有自己的属性和方法。对象有自己的属性和方法。
26+
&emsp;&emsp;**但是,为什么有的基本类型也可以调用方法呢?比如 123.length**
27+
&emsp;&emsp;那是因为除了 null、undefined 以外的基本类型都有与之对应的特殊的引用类型——包装类型。当代码被解释执行时,底层会将基本类型转换成引用类型,这样基本类型就可以调用与之相对应的引用类型的属性和方法。
2828

2929
#### <font color="#65A5EA" size="3">3. 数据类型判断的五种方法</font> {#say-goodbyte}
3030
**(1)typeof 返回数据类型,常用于判断除null之外的基本类型**
@@ -33,78 +33,101 @@ ECMA-262 把内置对象(built-in object)定义为“由 ECMAScript 实现
3333

3434
**(2)instanceOf 返回boolean,用于判断一个实例是否属于某种类型,会追溯原型链**
3535
除了Object 和 Function 之外,instanceof 自己等于false:
36-
Object instanceof Object //true
37-
Function instanceof Function //true
38-
Function instanceof Object //true
39-
Number instanceof Number //false
40-
String instanceof String //false
41-
var num1 = new Number(); num1 instanceOf Number //true
42-
var num2 = '123'; num2 instanceOf Number //false
36+
>Object instanceof Object //true
37+
>Function instanceof Function //true
38+
>Function instanceof Object //true
39+
>Number instanceof Number //false
40+
>String instanceof String //false
41+
>var num1 = new Number(); num1 instanceOf Number //true
42+
>var num2 = '123'; num2 instanceOf Number //false
4343
4444
**(3)Object.prototype.toString.call(xx) 用于获取XX正确的数据类型,返回[Object Type] 的字符串**
45-
因为所有类型都是 object 的实例,toString 方法可以读取对象的内部属性[[class]]
46-
为什么不直接使用 toString 呢?因为 toString 为 Object 的原型方法,而 Array、function、Date 等类型作为Object的实例,都重写了 toString 方法。
45+
&emsp;&emsp;因为所有类型都是 object 的实例,toString 方法可以读取对象的内部属性[[class]]
46+
&emsp;&emsp;为什么不直接使用 toString 呢?因为 toString 为 Object 的原型方法,而 Array、function、Date 等类型作为Object的实例,都重写了 toString 方法。
4747

4848
**(4)constructor 是 object 对象的一个属性,用于判断 object 类型的数据**
49-
var arr = [1,2,3];
50-
arr.constructor == Array //true
49+
>var arr = [1,2,3];
50+
>arr.constructor == Array //true
5151
5252
**(5)isArray es6提供的新方法,返回boolen,用于判断数组类型**
53-
var arr = [1,2,3];
54-
Array.isArray(arr) //true
53+
>var arr = [1,2,3];
54+
>Array.isArray(arr) //true
5555
5656
#### <font color="#65A5EA" size="3">4. 数据类型转换</font> {#say-goodbyte}
57-
**在条件判断时,除了 undefined, null, false, NaN, '', 0, -0,其他所有值都转为 true,包括所有对象。**
58-
另规定,console.log(null==null && undefined==undefined && null==undefined)
59-
**对象在转换基本类型时,会优先将值转换为原始值(toPrimitive优先级最高),再转换为数字(valueOf),最后转换为字符串(toString)。**
60-
**在 + 号两侧,如果一方不是字符串或数字,则会将它转换为字符串或数字:**
61-
'1'+'-2' //'1-2' 仅仅是字符串拼接
62-
[1,2]+[1,2] // '1,21,2'
63-
<font color="red" size="2">解析:数组调用 valueof 得到基本类型的值,所以调用 toString 把数组转成字符串 </font>
64-
**在 == 号两侧,会隐式地把布尔值转换成 number:**
65-
if({}){console.log(4)} //true -- 4
66-
if({}==false){console.log(5)} //false
67-
if({}==!{}){console.log(6)} //false
68-
if({}=={}){console.log(7)} //false
69-
70-
if([ ]){console.log(1)} //true -- 1
71-
if([ ]==false){console.log(2)} //true -- 2
72-
if([ ]==[ ]){console.log('')} //false
73-
if([ ]==![ ]){console.log(3)} //true -- 3
74-
<font color="red" size="2">解析:[ ]==![ ] ----> [ ]==false -----> [ ] == 0 -----> 0 == 0 --->//true </font>
75-
熟悉常见的优先级,如!非 的优先级最高。
57+
* **在条件判断时,除了 undefined, null, false, NaN, '', 0, -0,其他所有值都转为 true,包括所有对象。**
58+
* 另规定,console.log(null==null && undefined==undefined && null==undefined)
59+
* **对象在转换基本类型时,会优先将值转换为原始值(toPrimitive优先级最高),再转换为数字(valueOf),最后转换为字符串(toString)。**
60+
* **在 + 号两侧,如果一方不是字符串或数字,则会将它转换为字符串或数字:**
61+
>'1'+'-2' //'1-2' 仅仅是字符串拼接
62+
>[1,2]+[1,2] // '1,21,2'
63+
64+
<font color="red" size="2">解析:数组调用 valueof 得到基本类型的值,所以调用 toString 把数组转成字符串 </font>
65+
* **在 == 号两侧,会隐式地把布尔值转换成 number:**
66+
>if({}){console.log(4)} //true -- 4
67+
>if({}==false){console.log(5)} //false
68+
>if({}==!{}){console.log(6)} //false
69+
>if({}=={}){console.log(7)} //false
70+
71+
>if([ ]){console.log(1)} //true -- 1
72+
>if([ ]==false){console.log(2)} //true -- 2
73+
>if([ ]==[ ]){console.log('')} //false
74+
>if([ ]==![ ]){console.log(3)} //true -- 3
75+
><font color="red" size="2">解析:[ ]==![ ] ----> [ ]==false -----> [ ] == 0 -----> 0 == 0 --->//true </font>
76+
* 熟悉常见的优先级,如!非 的优先级最高。
7677

7778
#### <font color="#65A5EA" size="3">5. 深拷贝和浅拷贝</font> {#say-goodbyte}
7879
**基本类型和引用类型的区别是:**
7980
基本数据类型存储在栈中,引用类型存储在栈中的是一个地址,这个地址指向堆中的存储的对象;
8081
基本类型是传值,引用类型是传址,引用类型存在深浅拷贝。
8182
>*传值*
82-
>var a = 1;
83-
>var b = a;
84-
>b = 3;
85-
>console.log(b) //3
86-
>console.log(a) //1
83+
>var a = 1;
84+
>var b = a;
85+
>b = 3;
86+
>console.log(b) //3
87+
>console.log(a) //1
8788
8889
>*传址*
89-
>var a = {x:1,y:2};
90-
>var b = a;
91-
>b.x = 3;
92-
>console.log(b) //{x:3,y:2}
93-
>console.log(a) //{x:3,y2}
94-
当一个对象直接拷贝给另一个对象的时候,改变一个对象,另一个对象的数据也会相应改变,因为是拷贝的是地址,指向的是堆中的同一个对象。
95-
##### <font color="#65A5EA" size="2">浅拷贝</font>
96-
(1)Object.assign()
97-
>Object.assign(target, ...sources)
90+
>var a = {x:1,y:2};
91+
>var b = a;
92+
>b.x = 3;
93+
>console.log(b) //{x:3,y:2}
94+
>console.log(a) //{x:3,y2}
95+
96+
&emsp;&emsp;当一个对象直接拷贝给另一个对象的时候,改变一个对象,另一个对象的数据也会相应改变,因为是拷贝的是地址,指向的是堆中的同一个对象。
97+
98+
##### <font color="#65A5EA" size="2">浅拷贝(拷贝深度为一的引用类型)</font>
99+
(1)Object.assign()
100+
>Object.assign(target, ...sources)
98101
*//用于将所有可枚举属性的值从一个或多个源对象复制到目标对象。返回目标对象。*
99102

100-
>var a = {x:1,y:2};
101-
>var b = Object.assign({},a);
102-
>b.x = 3;
103-
>console.log(b) //{x:3,y:2}
104-
>console.log(a) //{x:1,y2}
105-
(2)扩展符
106-
##### <font color="#65A5EA" size="2">深拷贝</font>
107-
(1)JSON.parse(JSON.stringify(obj1))
103+
>var a = {x:1,y:2};
104+
>var b = Object.assign({},a);
105+
>b.x = 3;
106+
>console.log(b) //{x:3,y:2}
107+
>console.log(a) //{x:1,y2}
108108
109-
(2)递归
109+
(2)扩展符 ...
110+
>var a = {x:1,y:2};
111+
>var b = {...a};
112+
>b.x = 3;
113+
>console.log(b) //{x:3,y:2}
114+
>console.log(a) //{x:1,y2}
110115
116+
##### <font color="#65A5EA" size="2">深拷贝</font>
117+
(1)JSON.parse(JSON.stringify(obj1))
118+
&emsp;&emsp;obj2 = JSON.parse(JSON.stringify(obj1)); 用JSON.stringify把对象转成字符串,再用JSON.parse把字符串转成新的对象。
119+
&emsp;&emsp;缺点是:这种方法转换后会抛弃对象的constructor,只能转换Number, String, Boolean,Array,像undefined,RegExp对象和function不能被转换。
120+
>var a = {x:{m:1,n:0},y:2};
121+
>var b = JSON.parse(JSON.stringify(a));
122+
>b.x.m = 3;
123+
>console.log(b) //{x:{m:3,n:0},y:2}
124+
>console.log(a) //{x:{m:1,n:0},y:2}
125+
(2)递归 (只拷贝自身的属性)
126+
>function clone(obj){
127+
>> if(obj == unll || typeof obj !== 'object') return Object
128+
>> const newObj = new obj.constructor();
129+
>> for(let key in Object.getOwnPropertyDescriptors(obj)){
130+
>>> newobj[key] = clone(obj[key])
131+
>> }
132+
>> return newobj;
133+
>}

0 commit comments

Comments
 (0)