JS 块级作用域 函数声明

  1. var a = 0;
  2. console.log('No.1', a); // 0
  3. if (true) {
  4. console.log('No.2', a); // function a
  5. a = 1;
  6. console.log('No.3', a); // 1
  7. function a () {}
  8. console.log('No.4', a); // 1
  9. a = 2;
  10. console.log('No.5', a); // 2
  11. }
  12. console.log('No.6', a); // 1
var a = 0;

console.log('No.1', a); // 0

{
    console.log('No.2', a); // function a

  a = 1;

    console.log('No.3', a); // 1

  function a () {}

  console.log('No.4', a); // 1

  a = 2;

  console.log('No.5', a); // 2 
}

console.log('No.6', a); // 1

执行到块级作用域时,function a () 局部提升,所以 No.2 是 function a。
这时存在两个 a,一个是栈内存的 var a,一个是 堆内存中的 function a。

执行到 function a () {} 时,在执行期函数声明时会寻找和函数名相同的变量进行同步,这时会把保存在堆内存中的 a 同步给栈内存中的 a,值为 1。

No.5 访问的是堆内存地址,所以是 2,No.6 访问的全局的,即栈内存中的值,为 1。

原型链断裂(原型链与原型属性)

var obj1 = Object.create(null);

obj1.a = 1;

var obj2 = Object.create(obj1);

obj2.b = 2;

console.log(obj1.__proto__); // undefined
console.log(obj2.__proto__); // undefined

console.log(obj2.a); // 1
console.log(obj2.b); // 2

微信截图_20220112223952.png

使用 Object.create(null) 创建的对象,原型链被割裂,所以无法通过 __proto__访问原型链。
新版浏览器显示 [[Prototype]] 原型属性,继承关系仍然存在,所以仍然可以访问 obj1 的属性。

Object.keys() / Object.getOwnPropertyNames()

const obj = {};

Object.defineProperties(obj, {
    a: {
      value: 1,
    enumerable: true
  },
  b: {
      value: 2
  },
  c: {
      value: 3
  }
})

console.log(Object.keys(obj)); // ['a']
console.log(Object.getOwnPropertyNames(obj)); // ['a', 'b', 'c']

Object.keys() 只能访问可枚举的属性,Object.getOwnPropertyNames 更底层,可以获取对象实际属性。

对象 -> 枚举、数组 -> 遍历

switch 值匹配

let obj = { a: 1, b: 2 };
let arr = [ 1, 2, 3 ];

function test (key) {
  switch (key) {
    case obj:
      return 'obj';
      break;
    case arr:
      return 'array';
      break;
    default:
      return 'otther';
  }
}

console.log(test(obj)); // obj
console.log(test(arr)); // array

值匹配上将控制权交给该 case 的程序体, 只要值能匹配 ,都可以控制权交出去。输出目标值。