存储混乱
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
解析:
- No.1 正常执行为【0】
- 作用域中function a 是函数声明,会局部提升,放在作用域最开始
- No. 2 为 【function a】
- 此时,作用域内存在一个f(a),外部存在g(a)
- 执行完赋值,No.3 为 【1】
- 注意,只是提升了function a声明,function a(){}代码并未提升,依然会执行
- 会将此时的f(a)同步到g(a)中,(具体有待深挖)
- 作用域内始终是f(a),所以No4为【1】,赋值后,No5为【2】
- 由于【6】原因,NO6为【1】
原型链
var obj = { a: 1 }
console.log(obj)
浏览器更新了,[[prototype]] 标志替代之前的__proto__
原型的归属 -> 实例对象(__proto__)
原型对象 -> 构造函数的静态属性 (prototype)
function Test() {
this.a = 1;
}
Test.prototype.b = 2
Object.prototype.c = 3
const obj = new Test()
console.log(obj)
// test {
// a: 1,
// [[prototype]]: { // Test.prototype -> __proto__
// b: 2
// [[prototype]]: {
// c: 3
// }
// }
// }
原型链:从实例对象出发沿着 __proto__ 一直找到其原型,直到找到 Object.prototype 为止的这条链条
var obj1 = Object.create(null); // create ???
obj1.a = 1;
var obj2 = Object.create(obj1); // 原型
obj2.b = 2;
console.log(obj2.__proto__); // underfined
var obj3 = Object.create(obj2); // 原型
console.log(obj3.__proto__); // underfined 还是不行,原型链断了
__proto__ 其实是原型链的指针
__proto__ -> [] -> [[]] (都属于底层标志)
枚举与遍历
var obj = {
a: 1,
b: 2,
c: 3
}
var keyArr = Object.keys(obj) // [1,2,3]
var keyArr2 = Object.getOwnPropertyNames(obj); // [1, 2, 3]
Object.defineProperties(obj2, {
a: {
value: 1,
enumerable: true // 默认为false
},
b: {
value: 2,
},
c: {
value: 3,
}
})
var keyArr = Object.keys(obj2) // [1]
var keyArr2 = Object.getOwnPropertyNames(obj2); // [1, 2, 3]
obj -> 枚举属性
arr -> 遍历element
getOwnPropertyNames 更加底层,代码权限更高,会忽略enumerable属性
switch 分配机制
值匹配上将控制权交给该 case 程序体,只要值能匹配,都可以控制权交出去。输出目标值。
可以理解为 【===】,但是底层更多为 分支分配 ,计算机底层为0和1
switch (false) {
case 0:
console.log('0');
break;
case 1:
console.log('0');
break;
default:
console.log('Go away');
break
}
对象的switch -> 堆地址匹配
var a1 = { a: 1, b: 2 }
var a2 = { a: 1, b: 2 }
var a3 = a1
var a4 = Object.assign({}, a1)
var a5 = Object.assign(a3, a2)
function test(key) {
switch (key) {
case a1:
console.log('Object-1');
break;
case a2:
console.log('Object-2');
break;
default:
console.log('Other');
}
}
test(a1)
test(a2)
test(a3)
test(a4)
test(a5)