函数
JS 运行分三步:
语法分析(通篇扫描是否有语法错误),预编译(发生在函数执行的前一刻),解释执行(一行行执行)。
预编译执行分五步:
一、创建 AO 对象(Activation Object 执行期上下文)
二、找形参和变量声明,将变量和形参名作为 AO 属性名,值为 undefined. 变量声明提升(变量放到后面也不会报错,只是未定义类型)如:console.log(a);var a=10;结果 undenfined;
三、将实参值和形参统一(传参)
四、在函数体里面找到函数声明{函数声明整体提升(相当于放到程序最前面)}
五、值赋予函数体,执行(声明函数和变量的部分直接不看了)
作用域与变量声明提升
- 在 JavaScript 中,函数声明与变量声明会被 JavaScript 引擎隐式地提升到当前作用域的顶部
- 声明语句中的赋值部分并不会被提升,只有名称被提升
- 函数声明的优先级高于变量,如果变量名跟函数名相同且未赋值,则函数声明会覆盖变量声明
- 如果函数有多个同名参数,那么最后一个参数(即使没有定义)会覆盖前面的同名参数
函数参数是对象会发生什么问题?
function test(person) {
person.age = 26
person = {
name: 'yyy',
age: 30,
}
return person
}
const p1 = {
name: 'hy',
age: 25,
}
const p2 = test(p1)
console.log(p1) // -> {name: "hy", age: 26}
console.log(p2) // -> {name: "yyy", age: 30}
person = {}
这一步操作就将应用与原来的分离了
JavaScript 中,调用函数有哪几种方式?
- 方法调用模式 Foo.foo(arg1, arg2);
- 函数调用模式 foo(arg1, arg2);
- 构造器调用模式 (new Foo())(arg1, arg2);
- call/apply 调用模式 Foo.foo.call(that, arg1, arg2);
- bind 调用模式 Foo.foo.bind(that)(arg1, arg2)();
如何实现一个 new?
function _new(func, ...args) {
let obj = Object.create(func.prototype) // 原型
let res = func.apply(obj, args) // 初始化对象属性
return res instanceof Object ? res : obj // 返回值
}