导航
function 函数名(参数) {
// 执行语句
}
var test = function test1() {
console.log(test1.name); // test1 内部可见
}
console.log(test.name); // test1
test(); // 可执行
// test1(); // 报错,test1函数外部不可见
// 整体是个匿名函数表达式,function匿名函数这个值,这个整体是字面量
var test = function() {
var a = 1, b = 1; // 推荐
// var a = b = 1; //不推荐,此时的 b 并没有被 var ,b 为全局变量
}
var a = 10; // 10 这个值就是字面量
var a = function b() {
console.log(a, b); // [Function: b] [Function: b]
console.log(a.name, b.name); // b b
}
a();
function test(a, b) { // a, b 是形参
}
test(1, 2); // 1, 2 是实参
arguments.length
是 实参个数[function name].length
是 形参个数function test(a, b, c) {
console.log(arguments.length); // 实参有 2 个:1 跟 2
console.log(test.length); // 形参有3个:a, b, c
}
test(1, 2);
(function() {}).length; // 0
function sum() {
return [...arguments].reduce((total, cur) => total += cur, 0);
}
sum(1, 2, 3);
function test(a, b) {
a = 3;
console.log(arguments[0]); // 值为3,修改形参会影响 arguments 映射的值
b = 2;
console.log(arguments[1]);
// 值为undefined,由于没有传入形参对应的实参,导致更改形参无法改变 arguments 中对应的值
}
test(1);
function test() {
console.log('1'); // 1
return 123; // test函数返回123
console.log('2'); // 未被执行,不会打印
}
function test(a, b) {
console.log(a, b); // 1, undefined
}
test(1);
function test(a = 1, b = 2) {
console.log(a, b); // 1, 2
}
test();
function test(a = 1, b) {
console.log(a, b); // 1, 2
}
test(undefined, 2);
function test(a, b) {
var a = typeof(arguments[0]) !== 'undefined' ? arguments[0] : 1;
var b = typeof(arguments[1]) !== 'undefined' ? arguments[1] : 2;
console.log(a, b);
}
test();
test(); // 1
function test() {
console.log(1);
}
console.log(a); // undefined
var a;
function test() {
var a = b = 1;
}
test();
console.log(b); // 1 (b挂在了window,因为没有var声明)
console.log(window.b); // 1
console.log(a); // ReferenceError: a is not defined
console.log(window.a); // undefined
function test(a) {
console.log(a);
var a = 1;
console.log(a);
function a() {}
console.log(a);
var b = function() {}
console.log(b);
function d() {}
}
test(2);
// function a() {}
// 1
// 1
// function() {}
AO = {
a: undefined ->
2 ->,
function a(){} ->
1,
b: undefined ->
function() {},
d: function d() {}
}
function test(a, b) {
console.log(a);
c = 0;
var c;
a = 5;
b = 6;
console.log(b);
function b() {}
function d() {}
console.log(b);
}
test(1, 2);
// 1
// 6
// 6
AO = {
a: undefined ->
1 ->
5,
b: undefined ->
2 ->
function b() {} ->
6,
c: undefined ->
0,
d: function d() {}
}
console.log(a);
a = 2;
// 答案:
// ReferenceError: a is not defined
// vs
console.log(a);
var a = 2;
// 答案:
// undefined
function test() {
console.log(a);
a = 2;
}
test();
// 答案:
// ReferenceError: a is not defined
// vs
function test() {
console.log(a);
var a = 2;
}
test();
// 答案:
// undefined
console.log(a);
if (true) {
a = 2;
}
// 答案:
// ReferenceError: a is not defined
// vs
console.log(a);
if (true) {
var a = 2;
}
// 答案:
// undefined
// ----------
var a = 1;
{
a = 3;
console.log(a);
var a;
}
console.log(a);
// 答案:
// 3 3
function test() {
console.log(a);
if (true) {
a = 2;
}
}
test();
// 答案:
// ReferenceError: a is not defined
// vs
function test() {
console.log(a);
if (true) {
var a = 2;
}
}
test();
// 答案:
// undefined
{
a = 3;
}
console.log(a);
// 答案:
// 3 (a 不会提升 但会执行,挂载在 window 下)
// vs
console.log(a);
{
a = 3;
}
// 答案:
// ReferenceError: a is not defined
// vs
{
var a = 3;
}
console.log(a);
// 答案:
// 3
// ----------------------
if (true) {
a = 3;
}
console.log(a);
// 答案:
// 3
// vs
if (false) {
a = 3;
}
console.log(a);
// 答案:
// Uncaught ReferenceError: a is not defined
// ----------------------
if (true) {
var a = 3;
}
console.log(a);
// 答案:
// 3
// vs
if (false) {
var a = 3;
}
console.log(a);
// 答案:
// undefined
GO === window
var a = 1;
**function a() {**
console.log(2);
}
console.log(a);
*//* 答案:
// 1
GO = {
a: undefiend ->
function a(){} ->
1
}
console.log(a, b);
function a() {}
var b = function() {};
// 答案:
// function a() {} undefined
GO = {
b: undefined,
a: function a() {}
}
function test() {
var a = b = 1;
console.log(a);
}
test();
// 答案:
// 1
GO = {
b: 1
}
AO = {
a: undefined ->
1
}
var b = 3;
console.log(a);
function a(a) {
console.log(a);
var a = 2;
console.log(a);
function a() {}
var b = 5;
console.log(b);
}
a(1);
// 答案:
// function a(a) {}
// function a() {}
// 2
// 5
GO = {
b: 3
a: function a() {}
}
AO = {
a: undefined ->
1 ->
function a() {} ->
2,
b: undefined ->
5
}
AO = {
b: undefined ->
5
}
a = 1;
function test() {
console.log(a);
a = 2;
console.log(a);
var a = 3;
console.log(a);
}
test();
// 答案:
//undefined
// 2
// 3
GO = {
a: undefined ->
1,
test: function test() {}
}
AO = {
a: undefined ->
2 ->
3
}
function test() {
console.log(b);
if (a) {
var b = 2;
}
c = 3;
console.log(c);
}
var a;
test();
a = 1;
console.log(a);
// 答案:
// undefined
// 3
// 1
GO = {
test: function test() {},
a: undefined ->
1,
c: 3
}
AO = {
b: undefined
}
假定 if 中有一个函数声明 function a() {}
if 未执行时:
1.1
if 里的函数声明首先把变量名 a 提升到当前作用域(不是块作用域)的最顶部 a = undefined
if 执行时:
2.1
函数声明整体会被提升到块作用域顶部
2.2
执行到函数声明语句时,会把此刻块作用域里的 a 赋值到当前作用域同名变量 a
特殊情况
3.1
如果 if、代码块外边已经用 let 或者 const 声明了 a 变量,则 不执行 1.1
和 2.2
步骤
console.log(b);
if (true) {
console.log(b);
function b() {}
}
// 答案:
// undefined function b
// 分析:
// 因为if中,function b() {} 会被看做函数表达式
// 所以会把函数名 b 变量提升到当前作用域的最顶部(也就是全局执行器上下文),b 定义没值 undefined
// if 在执行时,会首先把函数声明提升到 if 代码块内部的顶端
// 所以内部打印 function b
var f = function() {return true;};
var g = function() {return false;};
(function() {
console.log(g);
if (g() && [] == ![]) {
f = function f() {return false;};
function g() {return true;};
}
})();
// 答案:
// 见下图
分析:
上面打断点会发现,function g的g变量是提升到if外边了,但此刻还是undefined。而iife外边的f,g此刻在iife中是可以访问的。但由于iife中有了同名g,所以还是undefined,然后if判断是g()由于g是undefined不是函数所以报错了。另外if中的f前面由于没有var ,所以改的是iife外边的f
function test() {
return a;
a = 1;
function a() {}
var a = 2;
}
console.log(test());
// 答案:
// function a() {}
function test() {
a = 1;
function a() {}
var a = 2;
return a;
}
console.log(test());
// 答案:
// 2
a = 1;
function test(e) {
function e() {}
arguments[0] = 2;
console.log(e);
if (a) {
var b = 3;
}
var c;
a = 4;
var a;
console.log(b);
f = 5;
console.log(c);
console.log(a);
}
var a;
test(1);
// 答案:
// 2 undefined undefined 4
// 分析:
go = {
a: undefined -> 1,
test: function test() {},
f: undefined -> 5
}
ao = {
a: undefined ->
4,
b: undefined,
c: undefined,
e: undefined ->
1 ->
function e() {} ->
2
}
var a = false + 1;
console.log(a);
// 答案:
// 1
// hint: 隐式转换,没有字符串,把非字符串转基本类型,再to number
var b = false == 1;
console.log(b);
// 答案:
// false
if (typeof(a) && (-true) + (+ undefined) + '') {
console.log('通过');
} else {
console.log('未通过');
}
// 答案:
// '通过'
// hint:
// 加减乘除的优先级高于 && ||
// typeof(a) => 'undefined' | (-true) => -1 | (+ undefined) => NaN
// if 中 => "undefined" && (-1 + NaN) + '' =>
// "undefined" && NaN + '' =>
// "undefined" && 'NaN' => true
if(1 + 5 * '3' === 16) {
console.log('通过');
} else {
consoel.log('未通过');
}
// 答案:
// '通过'
// hint: 乘法,会把非数字转数字 1 + 5 * '3' => 1 + 15
🍒 console.log(!!' ' + !!'' - !!false || '通过了');
// 答案:
// 1
// 分析:
// !! 是布尔值取两次反, 即 !!true 还是 true
// !!' ' => true | !!'' => false | !!false => false
// hint: ' ': 不是非空串,为真,两次取反,等于没反,最后为真
window.a || (window.a = '1');
console.log(window.a);
// 答案:
// '1'
// ()运算优先级高,所以先运行 window.a = '1' , 然后 window.a 就是真
function test() {
console.log(a);
if (false) {
function a () {}
}
}
test();
console.log(a);
// 答案:
// undefined 然后 报错 ReferenceError: a is not defined
var a = 0;
console.log('No.1', a);
{
console.log('No.2', a);
a = 1;
console.log('No.3', a);
function a () {}
console.log('No.4', a);
a = 2;
console.log('No.5', a);
}
console.log('No.6', a);
// 答案:
// No.1 0
// No.2 [Function: a]
// No.3 1
// No.4 1
// No.5 2
// No.6 1
// 分析:
// 1. {} 块作用域中 function a 的 a 变量提前到当前作用域(也就是全局作用域)
// 2. 开始执行 a = 0, 所以 No.1 的 a 是 0
// 3. 开始执行 {} 代码块中的内容,首先把 function a() {} 整体提升到块作用域顶部
// ,此刻块作用域中有了变量 a,所以 No.2 的 a 是 function a() {}
// 4. 接着 a = 1, 就把块作用域中的 function a 改成了 1,所以 No.3 的 a 是 1
// 5. 执行到 function a() {} 这一步时,
// 会把块作用域里的 a 赋值到全局同名变量 a,此刻全局 a 变成了 1
// 6. 接着 a = 2 ,把块作用域的 a 变成了 2,所以 No.5 的 a 是 2
// 7. No.6 打印全局 a ,是 1
/**
* go: {
* a: undefined -> 0 -> 1
* }
*
* ao: {
* a: function a -> 1
* }
*/
let a = 0;
console.log(a);
if (true) {
a = 1;
console.log(a);
function a() {}
a = 2;
console.log(a);
}
console.log(a);
// 答案:
// 0 1 2 0
// 分析:
// 这一题有点不一样,外部 a 是用 let 声明的 ,无法被 function a 覆盖
{
let a = 1;
function a() {}
}
// 答案:
// Uncaught SyntaxError: Identifier 'a' has already been declared
// 报错,暂时性死区