JS作用域
var a=10;
function aaa(){
console.log(a);
var a=20;
}
aaa(); //undefined
解释:aaa
函数里的变量进行了提升,相当于先声明了变量var a
,后面再进行赋值操作。
function aa(){ var a=b=10 };
console.log(b); //10
解释:var a=b=10
,相当于var a;b=10;a=b;
,未声明的b变成了全局变量
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
new Foo().getName(); //3
new new Foo().getName();//3
解释:
- 第一问,调用
Foo
的函数属性getName,直接执行Foo.getName
- 第二问,最后的函数声明进行了函数提升,所以最被
var getName
那一行的函数表达式给覆盖了 - 第三问,执行
Foo()
后重新用函数表达式覆盖了getName函数,最后返回的this相当于window对象 - 第四问,结果同上
- 第五问,成员运问符号
.
的优先级(18)大于new
无参运算符的优先级(17),因此这一问的代码相当于new (Foo.getName)()
- 第六问,
new
带参运算符优先级(18)等于成员运算符.
的优先级(18),因此这一问的代码相当于(new Foo()).getName()
- 第七问,根据优先级,这一问的代码相当于
new (new Foo()).getName)()
JS运算符
运算符优先级总结(从上到下依次递减)
- ()
- 成员符号., [], new()
- new
- 一元运算符
- 后置++, 后置–
- 前置++, 前置–, !, ~, 一元加法+, 一元减法-, typeof, void, delete, await
- 二元运算符
- **
- *, /, %
- +, -
- >>, <<, >>>
- <, <=, >, >=, in, instanceof
- =, !=, ===, !==
- &
- |
- &&
- ||
- ??
- ?:
- =
- yield, yield*
- …
- ,
var a = 1;
console.log(a++-1+a) //2
解释:第一个a++
返回的值为1,后面一个a返回的值为2,相当于1-1+2
var a = 1;
console.log(++a-1+a) //3
解释:第一个++a
返回的值为2,后面一个a返回的值也为2,相当于2-1+2