一、数组的拓展
1、Array.from();
用于将两种情况下的对象转化为数组:
(1)、类似数组的对象
(2)、可遍历的对象
参数
(1)、被转换的的对象。
(2)、map函数。
(3)、函数中this指向的对象。
let obj = {
render: function(x){
return x;
}
}
function a(){
var _arg = Array.prototype.slice.call(arguments);
var _from = Array.from(_arg,function(v){return this.render();},obj);
console.log(_arg); //[1,2]
console.log(_from); //[1,2]
}
a(1,2);
类数组中的length属性比实际属性多的情况下 会做截取
传入数组的情况下会返回新的数组,值传递
会忽略空位
2、Array.of();
生成一个数组或将一组值转换为数组。
主要用于规范 Array() 或者 new Array();
区别
Array.of(1) //[1]
Array.of(2,2) //[2,2]
Array.of(NaN) //
Array(2,2) //[2,2]
Array(1) //[undefined]
3、Array.find()
用于找出第一个符合条件的数组元素,找不到则返回undefined
参数
(1)callback
(2)函数中this指向的对象
回调函数中接收的参数
(1)、value
(2)、index
(3)、当前数组的引用
var a = [1,2,3,4,5];
a.find(function(value, index, arr) {
return value > 9;
})
4、Array.findIndex();
用于找出第一个符合条件的数组元素的下标,找不到则返回-1
和indexOf()的区别在于 对NaN 的识别
5、Array.fill();
用于填充一个数组
参数
(1)、要填充的元素
(2)、起始位置
(3)、结束位置 不包含
new Array(100).fill(10)
6、Array.keys() Array.values() Array.entries()
用于遍历数组。
区别
(1)、keys()是对键名的遍历
(2)、values()是对键值的遍历
(3)、entries()是对键值对的遍历
返回值
返回一个遍历器,可以用for...of循环进行遍历
var a = ['a','b'].entries()
for( let item of a ){
console.log(item); //[0, "a"][1, "b"]
}
for...in和Object.keys()区别在于继承
7、Array.copyWithin()
用于把这个数组的一部分元素复制到其他位置
参数
(1)开始替换的位置
(2)copy的起始位置
(3)结束位置
let arr = [1, 2, 3, 4, 5, 6, 7, 8];
arr.copyWithin(1, 5, 8);
console.log(arr);
拓展运算符...
let a = [1,2,3];
let b = [...a];
二、对象的拓展
几个简写
var f = {
url,
data(x , y){
return {x , y};
}
}
//等同于
var f = {
url: url,
data: function(x , y){
return {x:x , y:y};
}
}
属性名表达式
obj.a = 1;
obj['a' + 'asd'] = 2;
let prop = 'foo';
let obj = {
[prop]: true,
['a' + 'bc']: 123
};
定义方法名
let obj = {
['h' + 'ello']() {
return 'hi';
}
};
1、Object.is()
用来比较两个值是否严格相等。它与严格比较运算符(===)的行为基本一致
不同点
+0 === -0 //true
NaN === NaN // false
Object.is(+0, -0) // false
Object.is(NaN, NaN) // true
2、Object.assign()
用来将源对象的所有可枚举属性,复制到目标对象
参数
(1)、目标对象
(2)、源对象 可多个
同名属性 会覆盖 后面 覆盖前面
var target = { a: 1, b: 1 };
var source1 = { b: 2, c: 2 };
var source2 = { c: 3 };
Object.assign(target, source1, source2);
Object.assign(undefined) // 报错
Object.assign(null) // 报错
const v1 = 'abc';
const v2 = true;
const v3 = 10;
const obj = Object.assign({}, v1, v2, v3);
console.log(obj);
引用拷贝
同时也可以用于数组
Object.assign([1, 2, 3], [4, 5])
3、属性的遍历
(1)for...in
for...in循环遍历对象自身的和继承的可枚举属性(不含 Symbol 属性)。
(2)Object.keys(obj)
Object.keys返回一个数组,包括对象自身的(不含继承的)所有可枚举属性(不含 Symbol 属性)的键名。
(3)Object.getOwnPropertyNames(obj)
Object.getOwnPropertyNames返回一个数组,包含对象自身的所有属性(不含 Symbol 属性,但是包括不可枚举属性)的键名。
(4)Object.getOwnPropertySymbols(obj)
Object.getOwnPropertySymbols返回一个数组,包含对象自身的所有 Symbol 属性的键名。
(5)Reflect.ownKeys(obj)
Reflect.ownKeys返回一个数组,包含对象自身的所有键名,不管键名是 Symbol 或字符串,也不管是否可枚举。
4、Object.setPrototypeOf() Object.getPrototypeOf()
Object.setPrototypeOf()
用于设置一个对象的__proto__
参数
(1)、Object: 设置的对象
(2)、proto: proto值
如果第一个参数不是对象,会自动转为对象。但是由于返回的还是第一个参数,所以这个操作不会产生任何效果。
Object.getPrototypeOf()
用于获取
三、函数的拓展
1、rest 参数 表现形式为 ...values
function a(...values){
return values.sort();
}
a(1,2,3);
后面不允许跟参数
2、箭头函数
例如: const x = y => y;
function x(y){
return y;
}
x(){}
如果不需要参数 或者需要多个参数 就将参数部分用一个括号括起来
const x = () => 5;
const x = (v1,v2) => v1 + v2;
如果函数内部执行语句多于一条时,需要用大括号括起来
const x = (v1,v2) => { return v1 + v2; }
原因在于代码块
函数体内的this对象,就是定义时所在的对象,而不是使用时所在的对象。
不可以当作构造函数,也就是说,不可以使用new命令,否则会抛出一个错误
不可以使用arguments对象,该对象在函数体内不存在。如果要用,可以用 rest 参数代替
this指向原因
3、尾调用优化
就是指某个函数的最后一步是调用另一个函数。
以下三种情况,都不属于尾调用。
// 情况一
function f(x){
let y = g(x);
return y;
}
// 情况二
function f(x){
return g(x) + 1;
}
// 情况三
function f(x){
g(x);
}
特别针对 尾调用 调用递归
ES2017 允许函数的最后一个参数有尾逗号(trailing comma)。
四、class基本语法
function point(x,y){
this.x = x;
this.y = y;
}
point.prototype.toString = function(){
return '(' + this.x + ', ' + this.y + ')';
}
改写
class Point {
constructor(x, y) {
this.x = x;
this.y = y;
}
toString() {
return '(' + this.x + ', ' + this.y + ')';
}
}
方法之间不需要写逗号
ES6 的类,完全可以看作构造函数的另一种写法。
class Point {
}
typeof Point // "function"
Point === Point.prototype.constructor // true
在类的实例上面调用方法,其实就是调用原型上的方法。
class Point {
constructor(){
// ...
}
}
Object.assign(Point.prototype, {
toString(){},
toValue(){}
});
class里面定义的方法 都是不可枚举的
Object.keys(class)
Object.getOwnPropertyNames(class)
es5中的 是可以枚举的
生成类的实力方法和es5一样 都是通过new的方法来实现的 但是并不存在变量提升 必须在class下 去new
ES5 一样,实例的属性除非显式定义在其本身(即定义在this对象上),否则都是定义在原型上(即定义在class上)。
//定义类
class Point {
constructor(x, y) {
this.x = x;
this.y = y;
}
toString() {
return '(' + this.x + ', ' + this.y + ')';
}
}
var point = new Point(2, 3);
point.toString() // (2, 3)
point.hasOwnProperty('x') // true
point.hasOwnProperty('y') // true
point.hasOwnProperty('toString') // false
point.__proto__.hasOwnProperty('toString') // true
类也可以使用表达式的形式定义。
const MyClass = class Me {
getClassName() {
return Me.name;
}
};
类名为MyClass 而非 Me
let inst = new MyClass();
inst.getClassName()
Me.name
也可以写成立即执行函数
也可以使用get和set 去设定某个属性的get 和set
class MyClass {
constructor() {
// ...
}
get prop() {
return 'getter';
}
set prop(value) {
console.log('setter: '+value);
}
}
let inst = new MyClass();
inst.prop = 123; // set 123
inst.prop
Class 的静态方法
只需要在前面加 static 关键字
静态方法不会被new出来的实例继承,只能通过类来调用
比如
class foo{
static aaa(){
return 'hello';
}
}
new foo().aaa() // no