JavaScript与TypeScript总结

一、ES6标准

1.let、var、const

①let声明的变量只在let命令所在的代码块内有效。var声明的变量在全局都有效,代码块内会收到全局其他地方重复声明的影响。const将声明一个无法重复赋值的变量。

②var的变量提升:变量可以在声明之前使用,值为undefined。let不允许变量提升。

③“暂时性死区”(temporal dead zone,简称 TDZ):如果区块中存在letconst命令,这个区块对这些命令声明的变量,从一开始就形成了封闭作用域。凡是在声明之前就使用这些变量,就会报错。

let不允许在相同作用域内,重复声明同一个变量。var可以。

2.变量的解构赋值

①基本用法:

let [a, b, c] = [1, 2, 3];

②如果解构不成功,变量的值就等于undefined

③解构赋值允许指定默认值。

let [foo = true] = [];
foo // true

let [x, y = 'b'] = ['a']; // x='a', y='b'
let [x, y = 'b'] = ['a', undefined]; // x='a', y='b'

④字符串的解构赋值:

const [a, b, c, d, e] = 'hello';
a // "h"
b // "e"
c // "l"
d // "l"
e // "o"

类似数组的对象都有一个length属性,因此还可以对这个属性解构赋值。

let {length : len} = 'hello';
len // 5

⑤使用解构赋值交换变量的值

let x = 1;
let y = 2;

[x, y] = [y, x];

⑥遍历遍历 Map 结构

const map = new Map();
map.set('first', 'hello');
map.set('second', 'world');

for (let [key, value] of map) {
  console.log(key + " is " + value);
}

 3.函数的扩展

①利用参数默认值,可以指定某一个参数不得省略。

function throwIfMissing() {
  throw new Error('Missing parameter');
}

function foo(mustBeProvided = throwIfMissing()) {
  return mustBeProvided;
}

foo()
// Error: Missing parameter

②ES6 引入 rest 参数(形式为...变量名),用于获取函数的多余参数。

function add(...values) {
  let sum = 0;

  for (var val of values) {
    sum += val;
  }

  return sum;
}

add(2, 5, 3) // 10

注意,rest 参数之后不能再有其他参数(即只能是最后一个参数),否则会报错。

③严格模式

'use strict'

④name属性:调用XXX.name将返回这个XXX函数的函数名。

⑤嵌套的箭头函数

function insert(value) {
  return {into: function (array) {
    return {after: function (afterValue) {
      array.splice(array.indexOf(afterValue) + 1, 0, value);
      return array;
    }};
  }};
}

insert(2).into([1, 3]).after(1); //[1, 2, 3]
let insert = (value) => ({into: (array) => ({after: (afterValue) => {
  array.splice(array.indexOf(afterValue) + 1, 0, value);
  return array;
}})});

insert(2).into([1, 3]).after(1); //[1, 2, 3]

但是,一旦不注意,可读性就会呈几何级下降。

⑥尾函数优化

函数执行的时候有一个函数栈,在A函数中执行B函数,A函数的执行结果和调用点都会保存在函数栈中,因为B函数调用完会还得返回去执行A函数。当A函数的最后一步操作是执行B函数的时候,显而易见的,可以释放A函数在函数栈上的资源了。

典型应用就是,递归函数,只要递归函数的最后一步是执行其本身,那么就会使爆栈的几率大大降低。看一个Fibonacci 数列的例子:

function Fibonacci (n) {
  if ( n <= 1 ) {return 1};

  return Fibonacci(n - 1) + Fibonacci(n - 2);
}

Fibonacci(10) // 89
Fibonacci(100) // 堆栈溢出
Fibonacci(500) // 堆栈溢出
function Fibonacci2 (n , ac1 = 1 , ac2 = 1) {
  if( n <= 1 ) {return ac2};

  return Fibonacci2 (n - 1, ac2, ac1 + ac2);
}

Fibonacci2(100) // 573147844013817200000
Fibonacci2(1000) // 7.0330367711422765e+208
Fibonacci2(10000) // Infinity

遗憾的是,是否进行尾函数优化,是由编程语言跟编译器决定的。ES6支持,但是比如JAVA就不支持这个东西(JAVA不建议使用递归)。

4.数组的扩展

①扩展运算符“...”

将一个数组转为用逗号分隔的参数序列。

console.log(1, ...[2, 3, 4], 5)
// 1 2 3 4 5
// 可与其他参数一起使用

[...document.querySelectorAll('div')]
// [<div>, <div>, <div>]


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

const numbers = [4, 38];
add(...numbers) // 42

注意,扩展运算符如果放在括号中,JavaScript 引擎就会认为这是函数调用。如果这时不是函数调用,就会报错。

由于扩展运算符可以展开数组,所以不再需要apply方法,将数组转为函数的参数了。

还可以赋值数组:const a2 = [...a1];

还可以合并数组:const a4 = [...a1, ...a2];

还可以将字符串转为真正的数组:const a5 = [...'hello'] (任何定义了遍历器Iterator接口的对象,都可以用扩展运算符转为真正的数组。)

Map 和 Set 结构,Generator 函数都可以使用扩展运算符,比如 Map 结构:

let map = new Map([
  [1, 'one'],
  [2, 'two'],
  [3, 'three'],
]);

let arr = [...map.keys()]; // [1, 2, 3]

5.对象的扩展

①ES6 允许直接写入变量和函数,作为对象的属性和方法(只要你有一个引用,你甚至可以包括整个宇宙)。

let birth = '2000/01/01';

const Person = {

  name: '张三',

  //等同于birth: birth
  birth,

  // 等同于hello: function ()...
  hello() { console.log('我的名字是', this.name); }

};
function getPoint() {
  const x = 1;
  const y = 10;
  return {x, y};
}

getPoint()
// {x:1, y:10}

②属性遍历

ES6 一共有 5 种方法可以遍历对象的属性。官方推荐使用Object.keys返回一个数组,包括对象自身的(不含继承的)所有可枚举属性(不含 Symbol 属性)的键名。

遍历对象的键名,都遵守同样的属性遍历的次序规则。

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

Object.assign方法

Object.assign方法用于对象的合并,将源对象(source)的所有可枚举属性,复制到目标对象(target)。但是,Object.assign方法实行的是浅拷贝,而不是深拷贝。

const target = { a: 1 };

const source1 = { b: 2 };
const source2 = { c: 3 };

Object.assign(target, source1, source2);
target // {a:1, b:2, c:3}

同样的操作也可以进行对象克隆

function clone(origin) {
  let originProto = Object.getPrototypeOf(origin);
  return Object.assign(Object.create(originProto), origin);
}

为对象添加属性

class Point {
  constructor(x, y) {
    Object.assign(this, {x, y});
  }
}

为对象添加方法

Object.assign(SomeClass.prototype, {
  someMethod(arg1, arg2) {
    ···
  },
  anotherMethod() {
    ···
  }
});

// 等同于下面的写法
SomeClass.prototype.someMethod = function (arg1, arg2) {
  ···
};
SomeClass.prototype.anotherMethod = function () {
  ···
};

6.Symbol变量

①Singleton 模式

// mod.js
const FOO_KEY = Symbol.for('foo');

function A() {
  this.foo = 'hello';
}

if (!global[FOO_KEY]) {
  global[FOO_KEY] = new A();
}

module.exports = global[FOO_KEY];
const a = require('./mod.js');
console.log(a.foo);

这同时也是全局变量的设置方案,唔。

7.Set 变量

①成员的值都是唯一的,没有重复的值。四大方法:add、delete、has、clear。

Set函数可以接受一个数组(或者具有 iterable 接口的其他数据结构)作为参数,用来初始化。

// 例一
const set = new Set([1, 2, 3, 4, 4]);
[...set]
// [1, 2, 3, 4]

③利用Set给数组去重

// 去除数组的重复成员
[...new Set(array)]

给字符串去重

[...new Set('ababbc')].join('')
// "abc"

Array.from方法可以将 Set 结构转为数组。这就提供了去除数组重复成员的另一种方法。

function dedupe(array) {
  return Array.from(new Set(array));
}

dedupe([1, 1, 2, 3]) // [1, 2, 3]

8.Proxy

Proxy 用于修改某些操作的默认行为,等同于在语言层面做出修改,所以属于一种“元编程”(meta programming),即对编程语言进行编程。

其实就是一个拦截器,按照官方的描述,更像是一个C++的运算符重载,跟C#的set构造器有异曲同工之妙。它几乎可以作用于所有对象的行为,不仅仅是传参。(或许可以拿来弄一个enum)

一个技巧是将 Proxy 对象,设置到object.proxy属性,从而可以在object对象上调用。  var object = { proxy: new Proxy(target, handler) };

实现数组读取负数的索引

function createArray(...elements) {
  let handler = {
    get(target, propKey, receiver) {
      let index = Number(propKey);
      if (index < 0) {
        propKey = String(target.length + index);
      }
      return Reflect.get(target, propKey, receiver);
    }
  };

  let target = [];
  target.push(...elements);
  return new Proxy(target, handler);
}

let arr = createArray('a', 'b', 'c');
arr[-1] // c

9.JavaScript Array 对象的方法

常用方法:

push()  向数组的末尾添加一个或更多元素,并返回新的长度。

concat()  连接两个或更多的数组,并返回结果(a.concat(b))。

值得注意的是,若a是空的,就不能直接concat。

10.=== 和 ==的区别

===严格比较,类型不同就是不同;==会将两边转换成值再比较,比如string和int,1和‘1’是相等的。

原文地址:https://www.cnblogs.com/chrisweiii/p/10553934.html