#### 2. BAT筆試題中幾道關于堆棧內存和閉包作用域的題
~~~
//example 1
let a={}, b='0', c=0;
a[b]='珠峰';
a[c]='培訓';
console.log(a[b]); // 培訓
?堆:存儲引用類型的空間
棧:存儲基本類性值和執行代碼的環境
對象和數組的區別,數組可以看成是以數字為索引的對象
---------------------
//example 2
let a={}, b=Symbol('1'), c=Symbol('1');
a[b]='珠峰';
a[c]='培訓';
console.log(a[b]); //珠峰
~~~

對象的屬性名可以是字符串,sym,bol,布爾值,null,undefined,也就是基本類型值和symbol,但是如果數字和字符串一樣的話,屬于同一個屬性。
```
//example 3
let a={}, b={n:'1'}, c={m:'2'};
a[b]='珠峰';
a[c]='培訓';
console.log(a[b]); // 培訓
```
valueof 和toString的區別

~~~
//=>遇到會的題不要“慌”:你以為你以為的就是你以為的
// var test = (function (i) {
// return function () {
// alert(i *= 2);
// }
// })(2);
// test(5); "4"
// alert彈出來的都要toString
~~~
賦值,1:創建變量,2:準備值,3:關聯

~~~
var a = 0,
b = 0;
function A(a) {
A = function (b) {
alert(a + b++);
}; //A不是私有的
alert(a++);
}
A(1);
A(2);
~~~

深克隆淺克隆
~~~
let obj = {
a: 100,
b: [10, 20, 30],
c: {
x: 10
},
d: /^\d+$/
};
// let obj2 = {
// ...obj //淺克隆
// };
// let obj2 = {};
// for (let key in obj) {
// if (!obj.hasOwnProperty(key)) break;
// obj2[key] = obj[key]; //淺克隆
// }
// let obj2 = JSON.parse(JSON.stringify(obj)); //=>弊端?
~~~
正則,函數,對象,日期有弊端 => 不是正則了


~~~
// console.log(obj, obj2);
function deepClone(obj) {
//=>過濾特殊情況
if (obj === null) return null;
if (typeof obj !== "object") return obj;
if (obj instanceof RegExp) {
return new RegExp(obj);
}
if (obj instanceof Date) {
return new Date(obj);
}
//=>不直接創建空對象目的:克隆的結果和之前保持相同的所屬類
let newObj = new obj.constructor;
//或者 let newObj = new Object();
for (let key in obj) {
if (obj.hasOwnProperty(key)) {
newObj[key] = deepClone(obj[key]);
}
}
return newObj;
}
let obj2 = deepClone(obj);
console.log(obj, obj2);
console.log(obj === obj2);
console.log(obj.c === obj2.c);
~~~

~~~
function Foo() {
getName = function () {
console.log(1);
};
return this;
}
Foo.getName = function () {
console.log(2);
};
Foo.prototype.getName = function () {
console.log(3);
};
var getName = function () {
console.log(4);
};
function getName() {
console.log(5);
}
Foo.getName();
getName();
Foo().getName();
getName();
new Foo.getName();
new Foo().getName(); //new Foo()找prototype上的,實例找原型上的
new new Foo().getName();
~~~

~~~
async function async1() {
console.log('async1 start');
await async2();
console.log('async1 end');
}
async function async2() {
console.log('async2');
}
console.log('script start');
setTimeout(function () {
console.log('setTimeout');
}, 0)
async1();
new Promise(function (resolve) {
console.log('promise1');
resolve();
}).then(function () {
console.log('promise2');
});
console.log('script end');
~~~
定時器,時間綁定 ajax ----宏任務
promise async await ---微任務

#### 課后作業
**第一題:寫出下面代碼輸出的結果**
~~~javascript
function A(){
alert(1);
}
function Func() {
A=function(){
alert(2);
};
return this;
}
Func.A=A;
Func.prototype={
A:()=>{
alert(3);
//箭頭函數不能被new,因為沒有原型鏈prototype,就沒有constructor
}
};
A();
Func.A();
Func().A();
new Func.A();
new Func().A();
new new Func().A(); //會報錯
~~~
**第二題:寫出下面代碼輸出的結果**
~~~javascript
var x=2;
var y={
x:3,
z:(function(x){
this.x*=x;
x+=2;
return function(n){
this.x*=n;
x+=3;
console.log(x);
}
})(x)
};
var m=y.z;
m(4);
y.z(5);
console.log(x, y.x);
~~~
**第三題:寫出下面代碼輸出的結果**
~~~javascript
var a = ?;
if (a == 1 && a == 2 && a == 3) {
console.log(1);
}
~~~
**第四題:寫出下面代碼輸出的結果**
~~~javascript
var x=0,
y=1;
function fn(){
x+=2;
fn=function(y){
console.log(y + (--x));
};
console.log(x, y);
}
fn(3);
fn(4);
console.log(x, y);
~~~
**第五題:寫出下面代碼輸出的結果**
~~~javascript
setTimeout(() => {
console.log(1);
}, 20);
console.log(2);
setTimeout(() => {
console.log(3);
}, 10);
console.log(4);
console.time('AA');
for (let i = 0; i < 90000000; i++) {
// do soming
}
console.timeEnd('AA'); //=>AA: 79ms 左右
console.log(5);
setTimeout(() => {
console.log(6);
}, 8);
console.log(7);
setTimeout(() => {
console.log(8);
}, 15);
console.log(9);
~~~