废话不多说,看题,,,
var x = [12, 23];
function fn(y) {
y[0] = 100;
y = [100];
y[1] = 200;
console.log(y);
}
fn(x);
console.log(x);
=========前置知识==========
栈内存 ECStack 浏览器之所以能够运行代码,是因为提供了一个供代码运行的环境
就是在计算机中分配出来的一块内存
代码执行分为:全局代码,函数中代码,私有块中的代码
当前环境上下文形成后会有一个进栈的过程
VO(variable object)变量对象
代码在当前上下文中执行的时候,创建的变量总是会存储在当前上下文指定的变量对象中,所以变量对象就是用来存储当前上下文中创建的变量的
AO(Active Object)是VO的一种,VO用在全局上下文,AO用于块级上下文和函数上下文
基本类型和引用类型的区别
如果值是引用数据类型,不会直接存储在栈内存中,会开辟一个堆内存,用来存储自己的键值对,每一个堆内才能都有一个16进制的地址,在堆内存中分别存储键值对,把16进制的地址放到栈中,供变量调用
基本数据类型是按照值来操作,引用数据类型是按照地址来操作的
=========图解==========
=========详解==========
- 创建函数的时候都做了哪些事情:
- 开辟堆内存
- 把函数体内部的代码,当作字符串存储到堆中
- 把地址值存到栈中,供变量调用
- 创建函数的时候就声明了函数的‘作用域’,值就是当前函数创建时所处的上下文 注:创建函数但不执行,没有任何意义,堆里存储的就是一堆字符串。
- 函数执行的时候都做了哪些事情: 目的:是把之前创建函数的时候,在函数体中存储的代码字符串拿过去执行的
- 形成一个全新的私有上下文进栈执行
- 代码执行之前还要进行 初始化作用域链,初始化this的指向,初始化arguments,形参赋值,变量提升,最后代码执行
- 【作用域链】当前私有上下文下代码执行,遇到一个变量,首先看是否为自己的私有变量,如果是自己私有的,则接下来的操作,都是操作自己私有的,和其他上下文没有任何直接关系,如果不是自己私有的变量,则按照作用域链,向上级上下文中查找...如果上级也没有,一直找到全局上下文,如果全局也没有,设置变量值:相当于给window设置属性值,获取值,报错。
- 【this的指向】 5种:new出来的,.,箭头函数,强制改变,给当前元素的某个事件行为绑定方法
- 【初始化arguments】 在非严格模式下,把初始化的arguments和形参建立一个映射机制
- 【形参】是上下文中的私有变量,还包括在当前上下文创建的变量
- 【变量提升】把当前上下文中所有带var/function关键字的提前声明或者定义(带var只是提前声明,带function会提前的声明+定义)
- 一般情况下函数执行完后,为了优化栈内存空间,会把形成的私有上下文出栈释放掉【GC浏览器的垃圾回收机制】。但是当前上下文内部有堆内存被上下文以外的对象占用,形成的私有上下文就不会出栈释放,形成了 【闭包】 注:【】内的知识点很多,每个都可以单独拿出来写一篇。在这篇文章就先不赘述了哈
==========进阶==========
let a = 0,
b = 0;
function A(a) {
A = function (b) {
alert(a + b++);
};
alert(a++);
}
A(1);
A(2);