if
存储混乱
(a === 1 && a === 2 && a === 3)
/******************* 第一种解决方法**********************/
// a有toString的时候就会找自己的{ toString },没有的话就去Object.prototype上找toString方法。
// var a = {};
// console.log(a.toString()); // 默认是[object Object],调用Object.prototype上的toString方法。
// 所以要打到下面的条件可以给a添加toString方法。
var a = {
_a: 0,
toString() {
return ++this._a;
}
};
if (a == 1 && a == 2 && a == 3) {
console.log('Hello!');
}
/*******************第二种解决方法**********************/
// 通过get、set的方式。
var _a = 0;
Object.defineProperty(window, 'a', {
get() {
return ++_a;
}
});
if (a === 1 && a === 2 && a === 3) {
console.log('HELLo!');
}
/*******************第二种解决方法的语法糖**********************/
// 通过get、set的方式。
var obj = { _a: 0 };
Object.defineProperty(obj, 'a', {
get() {
return ++obj._a;
}
});
if (obj.a === 1 && obj.a === 2 && obj.a === 3) {
console.log('HELLO!');
}
预编译
let a = 0, b = 0;
function fn(a) {
fn = function fn2(b) {
console.log(++a+b)
}
console.log(a++)
}
fn(1);
fn(2);
// fn(1)执行的时候GO中的fn变成了function fn2(b) {...},所以再次执行fn(2)的时候就是执行fn2。
/*
GO={
a: 0,
b: 0,
fn: funcation fn(a) {...} => function fn2(b) { ... }
}
执行的时候:
fn(1) => fn2(1) => console.log(a++) => 1 => a = 2
fn(2) => fn2(2) => b=2 => console.log(++a+b) => a=3, b=2
*/
a.x = a = { n: 2 }
var a={n:1};
var b=a;
// js的赋值运算顺序永远都是从右往左的,不过由于“.”是优先级最高的运算符,所以这行代码先“计算”了a.x。
// 所以一开始a.x=undefined。
a.x=a={n:2}
console.log(a.x);
console.log(b.x)
new 中this的指向
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(); // 2
getName(); // 4
Foo().getName(); // 1
getName(); // 1
new Foo.getName(); // 2
/*
Foo.getName()的优先级比new的优先级高。
Foo.getName()执行后是 2.
*/
new Foo().getName(); // 3
/*
这里先执行new Foo()返回实例对象 => 调用实例的getName()方法 => Foo.prototype.getName() => function(){ console.log(3) }
*/
new new Foo().getName(); // 3
/*
这里的执行顺序是new (new Foo().getName()) 跟上面的过程一样。也是执行原型上的方法。
*/
/*
访问的优先级高低:
成员访问 = new (带参数列表) = 函数调用 > new (无参数列表)的优先级。
*/
/*
1、找变量和形参。
2、给形参赋值。
3、找函数声明。
4、执行函数。
Foo.getName()的执行过程:
Foo.getName() => function(){ console.log(2) } => 2
getName()的执行过程:
getName() => 找变量声明var getName = undefined => 找函数声明 getName = function() { console.log(5) } => 函数执行 => var getName = function() { console.log(4) } => 4
Foo().getName()的执行过程:
Foo() => return this 此时的this指向window => window.getName() => 此时Foo函数执行了,window.getName = function() { console.log(1) } => 1
*/