Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

引用数据类型的扩展 #50

Open
adodo0829 opened this issue May 6, 2020 · 0 comments
Open

引用数据类型的扩展 #50

adodo0829 opened this issue May 6, 2020 · 0 comments

Comments

@adodo0829
Copy link
Owner

引用数据类型的扩展

这里总结一些关于对象数据类型的扩展...

Object扩展

  • 规则
简洁表示法: 直接写入变量和函数作为对象的属性和方法({ prop, method() {} })
属性名表达式: 字面量定义对象时使用[]定义键([prop],不能与上同时使用)
方法的name属性: 返回方法函数名
  取值函数(getter)和存值函数(setter): get/set 函数名(属性的描述对象在get和set上)
  bind返回的函数: bound 函数名
  Function构造函数返回的函数实例: anonymous

属性的可枚举性和遍历: 描述对象的enumerable
super关键字: 指向当前对象的原型对象(只能用在对象的简写方法中method() {})
Object.is(): 对比两值是否相等
Object.assign(): 合并对象(浅拷贝),返回原对象
Object.getPrototypeOf(): 返回对象的原型对象
Object.setPrototypeOf(): 设置对象的原型对象
__proto__: 返回或设置对象的原型对象(不常用)
  • 对象的属性
描述: 
  自身、可继承、可枚举、非枚举、Symbol

遍历
  for-in: 遍历对象自身可继承可枚举属性
  Object.keys(): 返回对象自身可枚举属性键组成的数组
  Object.getOwnPropertyNames(): 返回对象自身非Symbol属性键组成的数组
  Object.getOwnPropertySymbols(): 返回对象自身Symbol属性键组成的数组
  Reflect.ownKeys(): 返回对象自身全部属性键组成的数组

规则
  首先遍历所有数值键,按照数值升序排列
  其次遍历所有字符串键,按照加入时间升序排列
  最后遍历所有Symbol键,按照加入时间升序排列

Array 扩展

  • 规则
扩展运算符(...): 转换数组为用逗号分隔的参数序列([...arr],相当于rest/spread参数的逆运算)
Array.from(): 转换具有Iterator接口的数据结构为真正数组,返回新数组
  类数组对象: 包含length的对象、Arguments对象、NodeList对象
  可遍历对象: String、Set结构、Map结构、Generator函数

Array.of(): 转换一组值为真正数组,返回新数组
copyWithin(): 把指定位置的成员复制到其他位置,返回原数组
find(): 返回第一个符合条件的成员
findIndex(): 返回第一个符合条件的成员索引值
fill(): 根据指定值填充整个数组,返回原数组
keys(): 返回以索引值为遍历器的对象
values(): 返回以属性值为遍历器的对象
entries(): 返回以索引值和属性值为遍历器的对象
数组空位: ES6明确将数组空位转为undefined(空位处理规不一,建议避免出现)
flat(): 扁平化数组,如果原数组有空位,flat()方法会跳过空位
  • 应用
克隆数组: const arr = [...arr1]
合并数组: const arr = [...arr1, ...arr2]
拼接数组: arr.push(...arr1)
代替apply: Math.max.apply(null, [x, y]) => Math.max(...[x, y])
转换字符串为数组: [..."hello"]
转换类数组对象为数组: [...Arguments, ...NodeList]
转换可遍历对象为数组: [...String, ...Set, ...Map, ...Generator]
与数组解构赋值结合: const [x, ...rest] = [1, 2, 3]
计算Unicode字符长度: Array.from("hello").length => [..."hello"].length

Function 扩展

默认值参数: 为函数参数指定默认值

形式: function Func(x = 1, y = 2) {}
参数赋值: 惰性求值(函数调用后才求值)
参数位置: 尾参数
参数作用域: 函数作用域
声明方式: 默认声明,不能用const或let再次声明
length: 返回没有指定默认值的参数个数
与解构赋值默认值结合: function Func({ x = 1, y = 2 } = {}) {}
应用: 
  1.指定某个参数不得省略,省略即抛出错误: function Func(x = throwMissing()) {}
  2.将参数默认值设为undefined,表明此参数可省略: Func(undefined, 1)

参数扩展符: 返回函数多余参数

语法: function Func(...rest) {}
形式: 以数组的形式存在,之后不能再有其他参数
作用: 代替Arguments对象
length: 返回没有指定默认值的参数个数但不包括rest参数

name属性: 返回函数的函数名

将匿名函数赋值给变量: 空字符串(ES5)、变量名(ES6)
将具名函数赋值给变量: 函数名(ES5和ES6)
bind返回的函数: bound 函数名(ES5和ES6)
Function构造函数返回的函数实例: anonymous(ES5和ES6)

箭头函数(=>): 函数简写

无参数: () => {}
单个参数: x => {}
多个参数: (x, y) => {}
解构参数: ({x, y}) => {}
嵌套使用: 部署管道机制

this指向固定化:
  并非因为内部有绑定this的机制,而是根本没有自己的this,
  导致内部的this就是外层代码块的this,因为没有this,因此不能用作构造函数

// 定义对象的方法,且该方法内部包括this,
// 因为对象不构成单独的作用域,导致say箭头函数定义时的作用域就是全局作用域
const person = {
  year: 9,
  say: () => {
    this.year--
  }
}

// 需要动态this的时候,也不应使用箭头函数
// 代码运行时,点击按钮会报错,因为button的监听函数是一个箭头函数,导致里面的this是全局对象
var btn = document.getElementById('btn');
btn.addEventListener('click', () => {
  this.classList.add('on');
});

尾调用

定义: 某个函数的最后一步是调用另一个函数
形式: function f(x) { return g(x); }
尾调用优化: 只保留内层函数的调用帧,删除外层函数的调用帧,减少内存开销

function f() {
  let m = 1;
  let n = 2;
  return g(m + n);
}
f();

// 等同于
function f() {
  return g(3);
}
f();

// 等同于
g(3);
// 调用g之后,函数f就结束了,所以执行到最后一步,
// 完全可以删除f(x)的调用帧,只保留g(3)的调用帧。
// 不过, 只有不再用到外层函数的内部变量,内层函数的调用帧才会取代外层函数的调用帧,
// 否则就无法进行“尾调用优化”。

尾递归

定义: 函数尾调用自身
作用: 只要使用尾递归就不会发生栈溢出,相对节省内存
实现: 把所有用到的内部变量改写成函数的参数并使用参数默认值,
让下一个函数运行时,保证之前的函数销毁,不再占用栈空间

// 这样会保留一个调用记录,复杂度 O(1)
function factorial(n, total) {
  if (n === 1) return total;
  return factorial(n - 1, n * total);
}
factorial(5, 1) // 120

function Fibonacci (n , ac1 = 1 , ac2 = 1) {
  if( n <= 1 ) { return ac2 };
  return Fibonacci (n - 1, ac2, ac1 + ac2);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant