// // 1. var,let与const关键字
// (function () {
// var c = d = 3; // 相当于d = 3; var c = d;
// // console.log(e); // 此处进入临时性死区:Uncaught ReferenceError: Cannot access 'e' before initialization
// let e = 5;
// })();
// console.log(c); // not defined 注意区分undefined
// console.log(d); // 3
// console.log(e); // not defined
// // 解析:var声明会被提升到块级作用域顶部,let和const会产生块级作用域,初始化之前访问会进入TDZ报错。
// // 2. let与const声明会产生TDZ
// var f = 1;
// if (true) {
// console.log(f); // Uncaught ReferenceError: Cannot access 'e' before initialization
// let f = 3;
// // const f = 3;
// }
// // 解析:let/const声明的变量不会提升
// // 3. 运算符优先级
// var a = { n: 1 };
// var b = a;
// a.x = a = { n: 2 };
// console.log(a.n, b.n); // 2 1
// console.log(a.x, b.x); // undefined { n: 2 }
// // 解析:
// // var b = a; ,此时a和b指向同一对象
// // .运算符优先级比=高,先计算a.x,此时b = {n:1, x: undefined}
// // 再计算=,赋值从右向左,所以此时a ={n: 2}, b = {n: 2, x: {n: 2}}
// // 4. 变量提升优先级
// console.log(func);
// var func;
// function func(a) {
// console.log(a);
// var a = 3;
// function a() {
// }
// };
// func(2);
// // function c(a) {
// // console.log(a);
// // var a = 3;
// // function a() {
// // }
// // }
// // function a() {
// // }
// // 解析:变量提升优先级:函数声明 > arguments > 变量声明
// // 5. 变量提升优先级
// var c = 1;
// function c(c) {
// console.log(c);
// var c = 3;
// }
// console.log(c); // 1
// c(2); // Uncaught TypeError: c is not a function
// // 解析:函数声明优先提升,当console.log(c); 执行的时候c已经被赋值为1
// // 再执行c(2)就会抛出TypeError,因为c已经不是函数了
// // 6. 变量提升
// var name = "A";
// (function name() {
// if (typeof name === 'undefined') {
// var name = 'B';
// console.log(name);
// } else {
// console.log(name);
// }
// })();
// // 输出:B
// // 解析:自执行函数执行时会先进行变量提升 var name = 'B';中变量name会先提升到当前作用域顶部
// // 7. 变量提升
// var a = 10;
// function test() {
// a = 100;
// console.log(a); // 100
// console.log(this.a); // 10
// var a;
// console.log(a); // 100
// }
// test();
// 8. 块级作用域
// foo(); // foo is not a function
// var a = true;
// if (a) {
// var foo = function () { console.log('a'); }
// } else {
// var foo = function () { console.log('b'); }
// }
// var 不会产生块级作用域
// bar(); // bar is not defined
// var b = true;
// if (b) {
// bar = function () { console.log('a'); }
// } else {
// bar = function () { console.log('b'); }
// }
// far(); // far is not a function
// var c = true;
// if (c) {
// function far() { console.log('a'); }
// } else {
// function far() { console.log('b'); }
// }
// 9. 块级作用域
// if (!('x' in this)) {
// var x = 1;
// }
// console.log(x); // undefined
// var 不会产生块级作用域
// 10. 变量提升
// var y = 1;
// function c(y, z) {
// console.log(y); // undefined
// y = 2;
// console.log(y); // 2
// };
// console.log(y); // 1
// c();
// 变量提升也有优先级, 函数声明 > arguments > 变量声明
// 相当于以下代码:
// function c(y, z) {
// console.log(y);
// y = 2;
// console.log(y);
// };
// var y;
// y = 1;
// console.log(y);
// c();
// 11. this指向
// var v = 1;
// var obj = {
// v: 2,
// del: function () {
// console.log(this);
// this.v *= 2;
// console.log(v);
// },
// };
// obj.del(); // this指向obj 1 注意此处v为1
// 12. this指向
// var name = 'A';
// var obj = {
// name: 'B',
// getNameFuc: function () {
// // console.log(this); // obj
// return function () {
// return this.name;
// }
// }
// }
// console.log(obj.getNameFuc()()); // 相当于闭包 this指向window,所以输出A
// 13. this指向
// var name = 'A';
// var obj = {
// name: 'B',
// getNameFuc: function () {
// var that = this;
// return function () {
// return that.name;
// }
// }
// }
// console.log(obj.getNameFuc()()); // 输出B,备份了this
// 14. this指向
// var name = 'A';
// var obj = {
// name: 'B',
// getNameFuc: function () {
// return function () {
// return this.name;
// }
// }
// }
// console.log(obj.getNameFuc().call(obj)); // 输出B,改变了this指向
// console.log(obj.getNameFuc().call(obj)); // 输出B,改变了this指向
// console.log(obj.getNameFuc().bind(obj)()); // 输出B,改变了this指向
// 19. 原型
function A() {
}
A.prototype.n = 1;
var b = new A();
A.prototype = {
n: 2,
m: 3
}
var c = new A();
console.log(b.n, b.m); // 1 undefined
console.log(c.n, c.m); // 2 3
// 2. ++a和a++
// var a = 10, b = 20, c = 30;
// ++a; // a = 11
// a++; // a = 11
// e = ++a + (++b) + (c++) + a++; // a = 13
// console.log(e); // 13 + 21 + 30 + 13
// 3. this指向问题
// var myObject = {
// foo: "bar",
// func: function () {
// var self = this;
// console.log("outer func: this.foo = " + this.foo); // bar
// console.log("outer func: self.foo = " + self.foo); // bar
// (function () {
// console.log("inner func: this.foo = " + this.foo); // undefined
// console.log("inner func: self.foo = " + self.foo); // bar
// }());
// },
// // 箭头函数中this指向有外围最近一层非箭头函数决定
// fn: () => {
// var self = this;
// console.log('this', this); // window
// console.log("outer func: this.foo = " + this.foo); // undefined
// console.log("outer func: self.foo = " + self.foo); // undefined
// },
// };
// myObject.func();
// myObject.fn();
// let PageHandler = {
// id: '123456',
// init: function () {
// console.log(this); // PageHandler
// document.addEventListener('click', function (e) {
// console.log(this); // document
// this.doSomething(e.type); // 抛出错误
// })
// },
// doSomething: function (type) {
// console.log(this); // PageHandler
// console.log('Handling ' + type + ' for ' + this.id);
// }
// }
// PageHandler.init();