console.log(a) // 输出函数
var a = 5
function a () {}function fn(a,b,a){
console.log(a);//function a(){}
console.log(arguments[0]);//1
console.log(arguments[2]);//function a(){}
function a(){
}
var a=5;
}
fn(1,2,3);函数预处理:函数开始运行时会创建跟参数名相同的变量并赋值再和arguments对象产生引用关系。
预处理阶段 function 优先级最高 预处理阶段发生冲突的变量名,会被优先级高的忽略掉。
函数读取中 arguments 优先级是最高的 比function 还要高。
(1)函数参数名称重复
function fn(a,b,a){
console.log(a)
var a=10;
console.log(arguments[0]);
console.log(arguments[1]);
console.log(arguments[2]);
}
fn(1,2,3); // 会输出什么?函数fn(),arguments[0] 优先级是最高,此时输出1,由于函数预处理,所有此时a已经被重新赋值变成了10
预处理阶段将变量保存在window域:会产生变量提前和函数声明提前的效果。
window{
fs : 指向函数,
as : undefined,
gs : undefined
}在执行阶段window域的情况
window{
f : 指向函数,
a : 1,
b : 2,
g : 指向函数
}//预处理阶段:声明提前
onsole.log('as',a)
console.log('fs',f)
console.log('gs',g)
// console.log('bs',b)
var a = 1;
b = 2;
function f (){console.log("11");}
var g = function(){console.log("22");};
// 执行阶段
console.log('as1',window.a)
console.log('fs1',window.f)
console.log('gs1',window.g)
console.log('bs1',window.b)如果声明发生冲突。那么在预处理的时候遵循两个规则:
a. 先扫描函数,再扫描var声明的变量;
b. 如果与之前的声明发生冲突的是函数,则覆盖;如果是var声明的变量,则忽略
// 后者覆盖前者
console.log(f);
function f() {console.log('1')}
function f() {console.log('2')}// 函数优先,后者忽略
console.log(f); // 执行函数
var f = 1
function f() {console.log('2')}
var f = 4console.log(abc) // undefined
var abc = 0 ;
var abc = function(){console.log('1')}(2)方法不允许有多个命名相同的形参
//正确写法
// 此写法是非严格模式,在预处理阶段函数内部会优先创建和参数相同的变量名,赋值和相同参数名的覆盖操作。
// 当然也不推荐这样写
function fn(a, a, y){console.log(a);}
fn(2,3,4);// 错误写法 Uncaught SyntaxError
// 这种写法视为严格模式'use strict'
function fn(a, a, y = 2){console.log(a);}
fn(2,3);(3) 严格模式和非严格模式
严格模式下:形参与arguments完全独立
'use strict';
function showValue(value){
value = "Foo"; // 形参和变量同名:赋值和覆盖,同时也是局部变量
values = "Foo"; // 全局变量
console.log(value); //"Foo"
console.log(arguments[0]); //非严格模式:"Foo";严格模式:"Hi"
}
showValue("Hi");
console.log('values ', values ) // 访问全局变量
console.log('value', value) // 报错