Skip to content

箭头函数 this 指向

箭头函数是 ES6 新增的功能。没有自己的 this、不能用作构造函数、没有 arguments 属性,可以使用简写语法。它内部的 this 指向,只和它定义的位置有关,永远指向函数外部的 this。

js
//
var count = 3;
var user = {
  count: 1,
  getCount() {
    // 定义在对象内部,永远指向对象user
    return () => {
      return this.count;
    };
  },
};
var func = user.getCount();
console.log(func.call({ count: 2 })); // 1

Promise 执行顺序

promise 构造函数内部属于同步任务,then 方法的回调函数属于微任务。js 执行机制,是先执行同步任务,执行完后发现有微任务再去执行微任务队列,最后执行宏任务。

js
new Promise(resolve => {
  console.log(1);
  Promise.resolve().then(() => console.log(2));
  resolve(
    new Promise(function (resolve) {
      console.log(3);
      resolve(4);
    })
  );
}).then(res => {
  console.log(res);
});
console.log(5); // 1,3,5,2,4

正则

js
//以 A 开头、接至少一个数字、接一个小写字母、接 0|1 个数字、接 B、结尾
console.log(/^A[\d]+[a-z]\d?B$/.test("A2g3B")); // true
console.log(/^A[\d]+[a-z]\d?B$/.test("A2gB")); //true
console.log(/^A[\d]+[a-z]\d?B$/.test("A22g3B")); // true
console.log(/^A[\d]+[a-z]\d?B$/.test("A23gb2B")); //false

// 千分位加逗号
"10000000".replace(/(?=\B(\d{3})+$)/g,',')
// 匹配一个空格,这个空格后为非边界,后跟至少一组三位数字。

循环应用和数据储存

引用类型数据,其指针存在栈内存,实际内容存在堆内存上。其指针指向实际储存在堆内存的起始地址

js
var var_a = { a: 1, b: 2 };
var var_b = { a: var_a, b: 3 };
var_c = var_b["a"];
// 此时var_c和var_b.a都保持对var_a的引用

var_b["a"] = var_a = { a: 5 };
// 代码从右往左执行,重置了var_a,其引用指向了{a:5}
// var_b.a指向更改后的var_a,也就是{a:5}

console.log(var_c["a"]); // 1
//var_c此时仍然指向var_a以前的值{a:1,b:2}

预解析&声明提升

代码执行分成两个阶段:

  • 预解析阶段:会把声明的变量和函数提升,变量设置为 undefined。函数优先级比较高,如果有同名变量,会先覆盖变量。
  • 执行阶段:从上往下执行
js
console.log(func(1, 2)); // 3
// 函数提升,优先级比变量高,此时执行声明的函数

var func = function (x, y) {
  // 函数表达式
  return x - y;
};
function func(x, y) {
  // 函数声明,优先级更高
  return x + y;
}
console.log(func(1, 2)); // -1
// 执行函数表达式时,把函数声明覆盖了。

运算符和隐式转换

js
var a = 0;
console.log(a++); // 返回值0
// a++ 符号在后面,先打印在++

console.log(a++ && ++a + 3); // 返回值是3+3=6
//有其他运算符 ++优先级更好先执行

var b = a++ && ++a + 3; // 5+3+8
var c = ++a || ++b; // 6 || 8 返回6。++b没有执行
console.log(a, b, c); // 6,8,6

console.log(5 - "3" + "2" - parseInt("3f")); // 19
// 运算和隐式转化

原型链

js
function A(x) {
  this.x = x;
  this.exec = function () {
    return this.x * 2;
  };
}
function B(x) {
  this.x = x;
  this.exexB = function () {
    return this.exec() + 1;
  };
}
B.prototype = new A(2);
// B的原型为A的实例:{x:2,exec:functon(){return this.x*2}}

var b = new B(1);
// b:{x:1,exexB:function(){return this.exec()+1}}

console.log(b.exexB()); // 3
// b本身没有exex()方法,原型prototype上有,同时也有x:2属性
// 原型方法里的this.x优先从实例b本身找,b有属性x:1

迭代器&运行原理

Object 对象没有实现 Symbol.iterator 迭代器接口。

js
// 使下面等式成立
let [a, b] = { a: 1, b: 2 };
//直接运行报错:Uncaught TypeError: {(intermediate value)(intermediate value)} is not iterable

Object.prototype[Symbol.iterator] = function () {
  return Object.values(this)[Symbol.iterator]();
};
// 给Object原型上添加Symbl.iterator接口:借用了数组迭代接口

let [a, b] = { a: 1, b: 2 };
console.log(a, b); // 1 2

根据 MIT 许可证发布