ES6新特性 _2

一、正则的拓展

1、RegExp 构造函数

new RegExp( ) 构造函数常用于正则匹配中。而ES 5和ES 6对该构造函数的用法也有所区别。

ES 5标准下:

const regex = new RegExp(/Abc/i)
regex //Abc  其中i为修饰符,代表着不区分大小写进行匹配。

ES 6标准下:

# 在ES 6的标准下,RegExp构造函数被允许写入两个参数。
第一个参数为被匹配串,第二参数为修饰符
const regex = new RegExp(/Abc/,'i')  //在ES 5中会出错
regex //Abc
const regex = new RegExp('Abc','i');
regex //Abc

2、RegExp新增属性

① RegExp.prototype.flags

返回该正则的修饰符。

let text = new RegExp(/Abc/,'i').flags;
text // i12

② RegExp.prototype.Unicode

返回是否设置了u修饰符的布尔值。

let boolean = new RegExp(/abc/,'u');
boolean // true
let boolean2 = new RegExp(/abc/)
boolean //false

③ RegExp.prototype.sticky

返回是否设置了y修饰符的布尔值。

let boolean = new RegExp(/abc/,'y');
boolean // true
let boolean2 = new RegExp(/abc/)
boolean //false

3、字符串能使用正则表达式的几个方法?

字符串对象共有 4 个方法,可以使用正则表达式:
match()、replace()、search()和split()。

4、u修饰符、y修饰符

ES6 对正则表达式添加了u修饰符,含义为“Unicode 模式”,用来正确处理大于\uFFFF的 Unicode 字符。

详情见文档 https://es6.ruanyifeng.com/#docs/regex

二、数值的拓展

1、二进制和八进制的表示

在JavaSrcipt中二进制和八进制分别用:0b和0o作为数值的前缀表示

在ES5版本后,在严格模式的要求后,八进制的表示不能用 “0”表示。但在ES 6的版本下,明确要求以0o来表示八进制数值

0b111110111 === 503 // true
0o767 === 503 // true
# 非严格模式
// 非严格模式
(function(){
  console.log(0o11 === 011);})() // true
  
  // 严格模式(function(){
  'use strict';
  console.log(0o11 === 011);
  })() //在ES5 严格模式下会出错

2、Number 对象的拓展

① Number.isFinite( )

该方法用于检查一个数是否有限,返回true或false。

Number.isFinite(100) //true

Number.isFinite(NaN) //false

② Number.isNaN( )

该方法用于检查一个数是否为NaN,返回true或false。

Number.isNaN(100) //false

Number.isNaN(NaN) //true

③ Number.parseInt( )、Number.parseFloat( )

ES6上的Number.parseInt( )、Number.parseFloat( ) 行为与ES5 保持一致,都是分别将数转为整型和转为浮点型。

只不过在ES6后,将该方法移植到ES6上。

Number.parseInt(3.4) //3

Number.parseFloat(3) //3.0

④ Number.isInteger( )

该方法用来判断一个数是否为整数。

如果对数据精度的要求较高,不建议使用,如果一个数低于javaScript认知,则会默认强制转换为0。

Number.isInteger(3.4) //falseNumber.isInteger(3) //trueNumber.isInteger(3.0) //true123

⑤ Number.isSafeInteger( )

这个方法用于检验某个数是否为安全整型,返回true和false。

JavaScript 能够准确表示的整数范围在-2^53 到 2^53 之间(不含两个端点),超过这个范围,无法精确表示这个值。

Number.isSafeInteger(13) //true

Number.isSafeInter(NaN) //false

3、Math 对象的拓展

详情见文档。https://es6.ruanyifeng.com/#docs/number

4、BigInt 数据类型

JavaScript 所有数字都保存成 64 位浮点数,这给数值的表示带来了两大限制:
:是数值的精度只能到 53 个二进制位(相当于 16 个十进制位),大于这个范围的整数,JavaScript 是无法精确表示的,这使得 JavaScript 不适合进行科学和金融方面的精确计算。
:是大于或等于2的1024次方的数值,JavaScript 无法表示,会返回Infinity。

# 超过16个十进制位,无法精确表示
Math.pow(2,16) === Math.pow(2,16) + 1 ;

# 超过2的1024次方的数值
Number.isFinite(Math.pow(2,1025)) //false  Infinity

为了解决上述的问题,ES6 2020版本推出了BigInt数据类型。用于表示2的1024次方或较大的数据。

语法如下:

# 与普通Int的区别:
1、BigInt需添加后缀n 
const num1 = 15346349309;
const num2 =  15346349309n;
num1 //Infinity
num2 //15346349309#
与普通Int的区别:
2、Int类型和BigInt类型数值并不相等
123 === 123n //false
typeof 123n //'BigInt'
#BigInt不能使用 + 号来表示整数

5、BigInt 对象

像以往的String、Int、Number数据类型一样,BigInt数据类型同样也提供其包装对象。

① BigInt 转换

将普通 整型 数值转换为BigInt类型。

语法如下:

BigInt(123) // 123n

BigInt 对象继承了 Object 对象的两个实例方法。

BigInt.prototype.toString()
BigInt.prototype.valueOf()

它还继承了 Number 对象的一个实例方法。

BigInt.prototype.toLocaleString()

更多请详细查看文档:https://es6.ruanyifeng.com/#docs/number

② BigInt 与其他数据类型转换

Boolean(1n) //true
Boolean(0n) //false
String(1n) //'1'
Number(10n) //10

三、函数的拓展

1、函数参数的默认值

在ES5之前,并不能为函数直接指定默认参数。只能通过变通传入参数,如果传入的参数为空,则处理成默认值。这样方式去解决。

function sayHi(val){
	if (typeof val === 'undefined') {
  		y = 'jack';
	}
	console.log('Hello'+val);
}
sayHi(); //hello jack

在ES6后,就可以指定参数的默认值了。语法如下:

function sayHi(val='jack'){
	console.log('Hello'+val);
}

sayHi(); //hello jack
sayHi(Bob); //hello Bob

# 函数的参数还可以和解构赋值一起使用

function add(x,y,z=3){
	return x + y + z;
}

add([1,2]); //6
add({x:1,y:2}); //6

# 在指定了参数默认值函数上length属性
# 此时length属性将返回没有指定 默认值的参数个数
const num = function(a){}.length; //num = 1
const num = function(a=1){}.length; //num = 0
const num = function(a=1,b,c){}.length; //num = 2

# 指定参数的默认值为 抛出不能省略该参数错误 的函数
function parError(){
	return new Error('该参数不能省略')
}
	
function add(val=parError()){
	return 'Hello ' + val;
}
	
add(); // 该参数不能省略
# 指定参数的默认值为 Undefined 表明该参数可以省略

2、Rest 参数

ES6 引入 rest 参数(形式为…变量名),用于获取函数的多余参数,这样就不需要使用arguments对象了。rest 参数搭配的变量是一个数组,该变量将多余的参数放入数组中。

语法如下:

function add(...values){
	var total = 0;
	for(var val of values){
		total +=val;
        }

        return total;
}

add([1,2,3]); //1+2+3 = 6

3、严格模式

在ES5中我们可以在函数内部使用 “use strict”,指定严格模式。

function num(){
	'use strict';
	x = 2; //会报错 x没有定义。如果不使用严格模式,
	//是不会报错的,因为存在变量提升的机制,变量可以先使用后声明。}12345

但在ES6中,对应严格模式作出了一点修改。
凡是对函数进行 参数指定默认值,参数解构,或者拓展运算符,Rest参数。均不能在函数内部显式设定严格模式。

function cal(val = 3){
	'use strict';
	//code 
}

cal() //报错

根据上面的要求,为什么不能在函数内部显式指定严格模式?

原因为:在调用一个函数时,如果对函数的参数进行以上处理,会先处理函数的参数再处理函数体,但由于函数体内使用了严格模式,而忽略掉参数的严格,所以会报错。

解决方法:
①设定一个全局的全局模式
②函数包在一个无参数的立即执行函数里面。

# 设定全局的严格模式
'use strict';
function cal(x=3){
	return x;
}
cal(); // 3

# 函数包在一个无参数的立即执行函数里面
const text =  (function(){
	'use strict';
	return function cal(x=3){
		return x;
	}
});
text; //3

4、箭头函数

在ES6中 允许使用 => 定义函数,甚至省略function 、return等关键字。便于简化函数。

基本语法:

# 无参数箭头函数
var x = ()=> 1;

var y = function(){
	return 1;
}

//x 与 y等同
	
# 一个参数的箭头函数
var x = x=>x;
var y  = function (x){
	return x;
}
x(1)
y(1);
//x 与 y等同

# 多个参数的箭头函数
var x = (a,b)=>a+b;
var y = function (a,b){
		return a+b;
};
x(1,2); //3
y(1,2); //3

# 只有一条语句且没有返回值的箭头函数

let fn = () => void doesNotReturn();

# 箭头函数与解构函数结合使用

let fn1 = ({age,sex}) = > console.log(age,sex);

fn1(person);

let fn2 = function(person){
	console.log(person.age,person.sex);
}
fn2(person);

使用注意点
箭头函数有几个使用注意点。

(1)函数体内的this对象,就是定义时所在的对象,而不是使用时所在的对象。

(2)不可以当作构造函数,也就是说,不可以使用new命令,否则会抛出一个错误。

(3)不可以使用arguments对象,该对象在函数体内不存在。如果要用,可以用 rest 参数代替。

(4)不可以使用yield命令,因此箭头函数不能用作 Generator 函数。

5、尾调用优化

什么是尾调用?

尾调用是函数式编程的一个概念。基本来说就是在某一个函数的结束位置以返回调用另外一个函数结束。

类似

function d(){
	return e();
}

什么是尾调用优化?
前提概念:我们知道,JavaScript进行函数的调用,会产生一个 “调用帧” ,存储着调用位置和内部变量等信息。

假设:一个函数A最后一步返回函数B的调用,即尾调用。会产生两层帧,即A函数调用帧和B函数调用帧。由于调用顺序是先作用函数A再作用函数B,以入栈的思想,函数A的调用帧在函数B之上。

此时有两个大的 “调用帧” 在 “调用栈” 中,而对于浏览器而言,因为函数A最后返回函数B,此时函数A调用帧的上的局部变量和调用位置就可以不保存了。

基于这点,浏览器会采用尾调用优化的手段,将函数A的调用帧里的局部变量的调用位置和信息等清除,以节省性能开销。达到优化的效果。

注意,目前只有 Safari 浏览器支持尾调用优化,Chrome 和 Firefox 都不支持。同时,ES6 的尾调用优化只在严格模式下开启,正常模式是无效的。

6、函数参数的尾逗号

一般来说函数最后一个参数不允许添加逗号。

在ES2017版本后,为了使函数的可读性更强,允许函数最后一个参数添加逗号。

function add(x,y,){code....} //在ES2017前该语法非法,在ES2017后合法1

7、可选参数的表示

ES6中可以在函数中定义可选参数。

语法如下:

# 用中括号[,args] 定义可选参数function([,value]){}

四、数组的拓展

1、拓展运算符

① 基本介绍与用法

拓展运算符是三个点 (…),它好比Rest参数的逆运算,将数组转换为以逗号分隔的参数序列。

# 一般性写法
console.log(...[1,2,3]) //1,2,3

# 分隔数组为以逗号分隔的参数序列
function add(x){
    return x + y;
}
let value  = add(...[3,7]);
value; //3+7 = 10

由于拓展运算符的存在,即可替代函数的apply( )方法。
(os:该方法用于将数组转换为函数的参数序列)

# ES5的写法
function add(x,y){
	return x + y;
}

let r = add.apply(null,[1,2]);
r; //1+2 =3

# ES6的写法
let r = add(...[1,2]);
r; //1 + 2 =3

# 拓展例子:在Math对象求最大数的例子上体现
# ES5写法
let max = Math.max.apply(null,[1,2,3])
max; //3

# ES6的写法
let max = Math.max(...[1,2,3])
max; //3

② 应用:数组复制

在以往,一个数组的复制,如果采用直接的复制。会得到指向同一份数据的另一个指针。如数组B直接复制数组A,数组B保存的数据并不是数组A的源数据,而是指向和数组A同一份数据的另一个指针。

弊端:根据上面,数组B和数组A同时指向同一份数据,如果数组B改变该数据时,数组A也会跟着改变。因为同时指向同一份数据。

var A = [1,2,3];
var B = A; //保存的是指向同一份数据的另一个指针
B;//[1,2,3]

# 当B发生改变时,A也会跟着改变
B.push(4);
B; //[1,2,3,4]
A; //[1,2,3,4]

后来为了ES5为了解决上述问题,便可以通过concat( )的方法对两个数组进行拼接,如数组A和数组B进行拼接,数组A则会以其本身数据的 “一份拷贝” 与B进行拼接。拼接成功后,无论B怎么修改,也不会影响数组A。但ES6使用拓展运算符,将更加简洁。
语法如下:

# ES5写法
var A = [1,2,3];
var B = A.concat(); //以A的一份数据拷贝进行拼接

B.push(4);
B;//[1,2,3,4]
A;//[1,2,3]

# ES6写法
var A = [1,2,3];
var B = [...A];

③ 应用:数组合并

可以使用拓展运算符 (…),对两个数组进行合并。但需要注意的是,该合并都是基于浅拷贝。所谓的 浅拷贝 指的是浅复制是指当对象的字段值被复制时,字段引用的对象不会被复制。即复制前后,都是引用同一个对象。如果原数组引用发生改变时,会直接反映新数组上。

var A = [1,2,3];
var B = [4,5,6];
var C = [...A,...B];
C; //[1,2,3,4,5,6];
A.push(0);

# 当A发生改变后
# 因为数组C的部分数据字段引用对象是原数组A,
# 所以原数组A发生改变时,会直接反映到C数组上。
C; //[1,2,3,0,4,5,6];

④ 应用:与解构赋值结合使用

var [A,...B] = [1,2,3,4,5,6];
A; //1
B; //[2,3,4,5,6]  形如[...B],以达到解构赋值与复制数组的目的

⑤ 应用:实现了 Iterator 接口的对象

对实现了 Iterator 接口的对象,如Map、set对象、Generator 函数。
具体参考文档:https://es6.ruanyifeng.com/#docs/array

2、数组对象多个方法的拓展

① Array.form( )

该方法用于将两类对象转为真正的数组:类似数组的对象(array-like object)和可遍历(iterable)的对象(包括 ES6 新增的数据结构 Set 和 Map)。

var point = {
	'0':'x',
	'1':'y'
}
# ES5的写法
var arr = [].slice.call(point);
arr;//['x','y']

# ES6的写法
var arr = Array.form(ponit);
arr;//['x','y']

② Array.of( )

该方法用于将一组值转换为数组。

# ES5的写法

var A = 12345;
var arr = A.split(',');

arr;//[1,2,3,4,5]

# ES6的写法
var A = 12345;
var arr = Array.of(A);
or 
var [..arr] = A;

arr;//[1,2,3,4,5]

4、数组实例多个方法的拓展

① copyWithin( )

使用该方法,从数组内部指定位置复制一个数到另一个位置上,会覆盖原数据,并返回新的数组。

语法如下:

# Array.prototype.copyWithin(target, start = 0, end = this.length)
# 参数说明:必需参数:target为从该位置开始替换数据。
可选参数:start为开始数据拷贝位置,默认为0,end为数据停止拷贝位置,默认为长度。
var arr = [1,2,3,4,5,6];
var newArr = arr.copyWithin(0,2,3); //意为拷贝2-3索引位置上的数据,并从索引位置0开始替换
newArr; //[3,4,3,4,5,6] 覆盖了1和2

② find( ) 和 findIndex( )

数组实例方法 find( )方法用于找出第一个符合条件的数组成员。

语法如下:

# 参数说明
# find( )方法参数为一个回调函数。每个数组成员依次执行该回调函数
# 返回值说明
# 如果找出符合条件的第一个数组成员,则返回该成员。
# 否则返回 undefind

var arr = [1,2,3,4,5];
var value = arr.find((val)=>val==3);
value;//3
var value2 = arr.find((val)=>val<0);
value2;// undefind

数组实例方法 findIndex( ) 用于找出一个符合条件的数组成员的 位置

语法如下:

# 与 find( )方法的区别
# find( ) 找到返回成员,找不到返回Undefind。
# findIndex( ) 找到返回成员的索引位置,找不到返回-1
var arr = [1,2,3,4,5];
var value = arr.findIndex((val)=>val==3);
value;//2
var value2 = arr.findIndex((val)=>val<0);
value2;// -1

③ fill( )

数组实例 fill( )方法用于以指定值填充数组。

语法如下:

# 参数说明
# fill( ) 方法第一个参数为填充值。(必需)
# fill( ) 方法还可以指定另外两个参数,用于指定填充起始和结束位置。(可选),默认为全部填充

# 指定一个参数时,默认为全填充
var arr = [1,2,3].fill('A');
arr;//['A','A','A']

# 指定多个参数
var arr = [1,2,3].fill(7,1,2);
arr; //[1,7,3];

④ entries( ) 和 key( )、values( )

ES6 提供三个新的方法entries(),keys()和values()用于遍历数组。

语法如下:

# 参数说明
# 三个方法均返回Itertor对象,配合for of循环对数组元素进行遍历
# entries( )对键与值进行遍历
# keys( )对键进行遍历 values( )对值进行遍历

let arr = ['a','b','c'];
for(let [index,value] of arr.entries( )){
	console.log(index,value); //0:a,1:b,2:c
}
	
for(let key of arr.keys()){
	console.log(key); //0,1,2
}

for(let value of arr.values()){
	console.log(value); //'a','b','c'
}

⑥ includes( )

该方法用于查找数组中是否存在某个值。

在ES5的版本用include( ) 去寻找某个值是否存在数组中,但由于include( )的比较为 ===,可能会对NaN进行误判。由此ES6新提出了Includes( ) 用来查找数组中是否存在某个值。

语法如下:

# 参数说明
# inclues( )方法第一个参数为搜索值。(必需)
# 第二个参数和第三个参数分别为开始搜索位置和结束搜索位置。(可选)
# 返回值说明
# 找到返回true 反之返回 false
[1,2,3].includes(3);//true
[1,2,3].includes(4);//false

⑦ 数组扁平化处理 flat( ) 和 flatMap( )

数组有时候成员还是数组,为了解决嵌套的问题,ES6提出了flat( )方法,数组的实例方法 flat( ) 用于将 数组中的数组成员进行扁平化处理,将该成员取出并加到原有的位置上。

flat( ) 方法语法如下:

# 参数说明  如果原数组有空位,flat()方法会跳过空位。
# flat(args) 参数用于指定 扁平化层数。默认为1 # 如果扁平化多层,都要转成一维数组。可以用Infinity关键字作为参数
# 返回值说明
# 该方法返回一个新数组,对原数组无影响.

# 扁平化一层
var arr1 = [1,[2,3],4].flat();
arr1;//[1,2,3,4]
var arr2 = [1,[2,3],[4]].flat();
arr2; //[1,2,3,4]

# 扁平化两层
var arr2 = [1,[2,3],[4,[5,6]]].flat(2);
arr2; //[1,2,3,4,5,6]

# 扁平化三层
var arr3 = [1,[2,3],[4,[[5],6]]].flat(3);
arr3; //[1,2,3,4,5,6]

# 扁平化多层
var arr4 = [1,[2,3],[4,[5,6,[7,[8,9]]]]].flat(Infinity);
arr4; //[1,2,3,4,5,6,7,8,9]

# 如果原数组有空位 flat()方法会跳过空位。
var arr5 = [1, ,3,4].flat();
arr5; //[1,3,4]

flatMap( )与flat( )功能一致。

flatMap( ) 用于将每个数组成员执行一个函数,并对该函数的返回值执行一次flat( )方法。

flatMap( ) 语法如下:

# 参数说明
# flatMap(function(){.....}) 参数为一个历遍函数,每个数组成员执行一次。
# 然后对该函数的返回值执行一次 flat()函数。
# 返回值说明
# 返回一个新扁平化数组,不影响原数组。
# 注意
# flatMap()只能展开一层数组。

//该方法相当于 [[1,2],[2,3],[3,4]].flat();
var arr  = [1,2,3].flatMap((x)=>[x,x+1]);
arr;//[1,2,2,3,3,4]

#flatMap()方法的参数是一个遍历函数,该函数可以接受三个参数,分别是当前# 数组成员、当前数组成员的位置(从零开始)、原数组。
//注意这里展示的语法 中括号[] 代表该参数为可选参数,如[,thisArg] 即为可省参数

arr.flatMap(function callback(currentValue[, index[, array]]) {
  // ...
  }[, thisArg])
  
  # flatMap()方法还可以有第二个参数,用来绑定遍历函数里面的this

五、对象的拓展

1、对象属性的简洁写法:无须再次定义属性名

在ES6的版本后,允许在大括号直接写入变量和函数,作为对象的属性和方法。此时变量名即为属性名,变量值即为属性值,函数同理

# ES5写法 需定义对象属性名再传入对应属性值
const x = 'A';
let el = {x:x};
el; //{x:'A'}

# ES6写法 允许直接写入变量和函数,无须再次定义属性名。
const x = 'A';
const y = function(){code....};
let el = {x,y};
el; //{x : 'A',y : function(){code...}}

function f(x,y){
    return {x,y
}; //等同于return {x:x,y:y}}

f(1,2); //Object {x:1,y:2}

# ES6允许以表达式的形式定义属性名,但必须放在方括号内[],称为属性名表达式
let el = {
	['hell'+'o']:2
}

el;//Object {hello:2}
el.hello;//2
	
# 注意属性名表达式不能和简洁表示一起写
let hello = 2;
let el = {
    [hello]
}; 

el;//异常错误

2、对象方法的简洁写法:内部定义函数时无须function关键字

在ES6版本中允许在大括号中定义函数时省略function( )关键字。

# ES5写法
fuction y(){code...}
const el = {y:y};
el://Object {y:function(){code....}}

#ES6写法 内部定义时可省略function( )关键字
const el = {
	y(){code...}
}
el;//Object {y:function(){code...}}

# 拓展:对应对象的set 和 get 方法实际上无论是ES5还是ES6都是省略
# function()关键字的写法,只不过在ES6中,将这写法延伸至普通函数上。
# ES5 and ES6
const el = {
	//一般set和get方法用于在私有变量上.私有变量定义有两种方法处理
	//一、以下划线约定命名_xxxx,依然能访问,治标不治本
	//二、采用闭包的方式处理,将变量定义在闭包体内
	_x:0,  //这个是私有变量
	set x(){x+1},
	get x(){return this.x}
}

3、对象的拓展运算符

拓展运算符(…)同样能在对象中作用,对对象进行复制和合并等操作。

语法如下:

let age = 18,sex = 'fmale';
let el = {age,sex};
# 复制对象
let e2 = {...el};
# 合并对象
let age2 = 19,sex2 = 'male';
let e3 = {age2,sex2};
let e4 = {...e1,...e3};
e4;//Object {age:18,age2:19,sex:'fmale',sex2:'male'};
# 注意
# 当原对象的自定义属性和合并对象的属性名重名时
# 原对象在前,合并对象在后。合并对象对应原对象的同名属性会覆盖。反之。
let age = 18,sex = 'fmale';
let el = {age,sex};
let e2 = {
	age:19,
	sex:'male'
	}
let e3 = {...e1,...e2};
e3;//Object {age:19,sex:male} 前者覆盖后者

4、对象的新方法

① Object.assign( )

用于将源对象的 ”可枚举对象“ 复制到目标对象中。

语法如下:

# 参数说明
# Object.assign(target,Object1,Object2....)
# 第一个参数为目标对象,其余参数为源对象
let target = {a:1,b:2};
let Object = {c:3,d:4};
let newObject = Object.assign(target,Object);
newObject; //{a:1,b:2,c:3,d:4}# 注意:该拷贝 (复制)为浅拷贝。

② Object.is( )

用于判断两个对象是否 “严格” 相等。与===类似

let x = 1;
Object.is(x,x); // true
Object.is({x},{x});      // false

③ 对原型对象更好的拓展

在ES6之前,ES5版本中对象采用__proto__方法去引用该对象的原型对象。但奈何__proto__ 这个属性,在语义上并不友好,且兼容性差。 为此,ES6推出了更多的对象方法用于操作原型对象。
具体如下:
Object.setPrototypeOf( object, prototype ) 用于写操作
Object.getPrototypeOf( ) 用于读操作
Object.create( ) //用于创建操作

语法如下:

# 1、为Object的原型设置一个原型,可达到继承的效果
Object.setPrototypeOf(obj,prototype);
# 等同于
function setPrototypeOf(obj,prototype){
	//这里的Obj为传入的一个对象实例
	//使用对象实例的内部指针__proto__,获得对象的原型
	//最终Object的原型指向另一个原型prototype
	obj.__proto__ = prototype;
	return obj;
}

# 1、例子 
var behavior = "eat";
let animal = {behavior};
let dog = {};//dog.__proto__ = new animal;
//dog原型对象指向animal的实例,
//在内部就会有dog原型对象指向animal原型对象的指针,达成继承
Object.setPrototypeOf(dog,animal);
dog.hehavior; //eat
animal.age = 10;
dog.age;//10 子类读取父类属性
# 2、获得一个原型对象
Object.getPrototypeOf(obj);
function dog(){}
Object.getProtoypeOf(new dog()) === dog.prototype


# 3、创建一个原型对象 与Object.setPrototypeOf()类似
# 为一个原型对象追加一个原型对象
# 其返回值就是被追加原型对象后的原型对象
Object.create(obj,protoype);

④ 对Object对象的历遍对象更好的补充

let human = {age:18,sex:'fmale'};
Object.keys(human); //[‘age’,'sex'] 键数组

在ES6后推出Object.keys( )配套使用的Object.values( )和Object.entries( )方法,供for of配套使用。

# Object.keys() 以对象中的能遍历对象以键进行遍历
# 返回值为以键作为值的数组

let human = {age:18,sex:'fmale'};

for ( let key of Object.keys(human)){
	consolo.log(key); //age,sex
}

# Object.values( ) 以对象中的能遍历对象以值进行遍历
# 返回值为以值作为值的数组
let human = {age:18,sex:'fmale'};

for ( let value of Object.values(human)){
	consolo.log(value); //18,fmale
}

# Object.entries( ) 以对象中的能遍历对象以键值对进行遍历

# 返回值为以键值对作为值的数组

let human = {age:18,sex:'fmale'};
// 对返回值进行解构赋值
for ( let [key,value] of Object.entries(human)){
	consolo.log(key,value); //age:18,sex:'fmale'
}
	
# 拓展 Object.formEntries() 该方法为Object.entries()的逆操作
# 用于将键值对数组转换为对象
let human = [
	['age',18],
	['sex','fmale']
]
Object.formEntries(human);
humun;//{age:18,sex:'fmale'}

# 更多方法 
# Object.getOwnPropertyNames(obj) 返回对象中所有非Symbol属性的键名,不含继承。
# Object.getOwnPropertySymbols(obj) 返回对象中所有Symbol属性的键名,不含继承。
# Reflect.ownKeys(obj) 返回对象中所有属性的键名,不含继承。


评论 (0)

发表评论

上一篇: ES6新特性 _1 下一篇: ES6新特性 _3