20200702

@xiaojingzhao

Plan

  • 你不知道的 js 下册 第七章 元编程

Notes

函数名称

函数具有 name 属性:

var abc = function () {
  //
};
abc.name; // "abc"

// 匿名函数
(function () {}.name); // ""

// generator
(function* () {}.name); // ""

class Awesome {
  contructor() {} // Awesome
  funny() {} // funny
}

var o = {
  foo() {}, // foo
  *bar() {}, // bar
  baz: () => {}, // baz
  bam: function () {}, // bam
  get qux() {
    // get qux
    return "aa";
  },
  set fuz(val) {}, // set  fux
  ["b" + "iz"]: function () {}, // biz
  [Symbol("buz")]: function () {}, // Symbol("buz")
};

// bind
var x = o.foo.bind(o); // bound foo
(function () {}.bind(o)); // bound

// esm
export default function () {} // default

// 通过 new 关键字
var y = new Function(); // anonymous
var GeneratorFuntion = function* () {}.__proto__.constructor;
var z = new GerneratorFuntion(); // anonymous

new.target

在构造器调用中,new 会形成一个虚拟上下文

class Parent {
  constructor() {
    if (new.target === "Parent") {
      console.log("111");
    } else {
      console.log("222");
    }
  }
}
class Child extends Parent {}
var a = new Parent(); // 111
var b = new Child(); // 222

Symbol 公开符号

  • Symbol.iterator 一个构造迭代器的方法。可以自定义来覆盖原有的迭代器
  • Symbol.toString + Symbol.hasInstance

Symbol.toString 指定了在[Object xxx] 字符串化时使用的字符串值

function Foo() {}
Foo.toString(); // function Foo() {}

Symbol.hasInstance 是构造器函数上的一个方法,接受实例对象值,通过返回 true 或者 false 来指示这个值是否可以成为一个实例

a = new Foo();
a instanceof Foo; // 可以覆盖原生 instanceof
  • Symbol.species 生成新实例时,内置方法使用哪一个构造器

String 中正则表达式相关的内置方法覆盖

  • Symbol.match
  • Symbol.search
  • Symbol.replace
  • Symbol.split

Symbol.isConcatSpreadable

用来指示如果把它传给一个数组的 contact(...)是否应将其展开。

var a = [1, 2, 3];
var b = [4, 5, 6];

b[Symbol.isConcatSpreadable] = false;

[].contact(a, b); // [1, 2, 3, [4 ,5, 6]]

Symbol.unscopables

var o = {
  a: 1,
  b: 2,
  c: 3,
};
o[Symbol.unscopables] = {
  a: false,
  b: true,
  c: false,
};

var a = 10,
  b = 20,
  c = 30;

with (o) {
  console.log(a, b, c); // 1 20 3
}
  • true 表示 unscopable,不会被包含到词法作用域中
  • false 相反

More