💎一站式轻松地调用各大LLM模型接口,支持GPT4、智谱、星火、月之暗面及文生图 广告
1.**ECMAScript中的所有参数传递的都是值,不可能通过引用传递参数。** 2.**五种基本数据类型是按值访问的**,因为可以操作保存在变量中的实际值。引用类型的值是保存在内存中的对象。与其他语言不同,JavaScript不允许直接访问内存中的位置,也就是说不能直接操作对象的内存空间。在操作对象时,实际上是在操作对象的引用而不是实际的对象。因此,**引用类型的值是按引用访问的。(实际上这种说法并不严密,当复制保存着对象的某个变量时,操作的是对象的引用。但在为对象添加属性是,操作的是实际的对象。)** 3.对于引用类型的值,我们可以为其添加属性和方法,也可以改变和删除其属性和方法。但是,我们不能给基本类型的值添加属性,尽管这样做不会抛出错误。这说明只能给引用类型动态地添加属性,以便将来使用。 4.复制引用操作时,复制操作结束后,两个变量实际上将引用同一个对象。因此,改变其中一个变量,就会影响另一个变量。 5.**ECMAScript中所有参数都是按值传递的。当我们给函数传入参数时,实际就是把函数外部的值复制给函数内部的参数,这和把值从一个变量复制到另一个变量一样。** 为了说明函数的参数是按值传递的,请看下面的例子: ~~~ function setName(obj) { //相当于省略了var obj = person; obj.name = ‘Nicholas’; obj = new Object(); //重写了obj的值,这时候obj与person引用的对象无关了。 obj.name = ‘Greg’; } var person = new Object(); setName(person); alert(person.name); //‘Nicholas’ ~~~ **个人理解:如果参数是按引用传递的话,那么obj和person应该始终指向同一个对象,实际上把person传入到setName中只不过是把person指向的对象的指针副本复制给obj。给ECMAScript函数传变量,相当于把外部变量赋值给函数内的局部变量。** 另一个面试中常见的陷阱: ~~~ var foo = { bar: function(){return this.baz;}, baz: 1};  (function(){return typeof arguments[0]();})(foo.bar); //undefined ~~~ 相当于arguments[0] = function(){return this.baz;} 6.***instanceof操作符用于检测变量的具体引用类型***。如果变量是给定引用类型的实例,则返回true。 语法:result = variable instanceof constructor; 7.在Web浏览器中,全局执行环境被认为是window对象,因此所有全局变量和函数都是作为window对象的属性和方法创造的。**某个执行环境中的所有代码执行完毕后,该环境被销毁,保存在其中的所有变量和函数定义也随之销毁**(全局执行环境直到应用程序退出--例如关闭网页或浏览器--时才会被销毁)。 8.延长作用域链的方法有两个: --try-catch语句的catch块 --with语句 这两个语句都会在作用域链的前端添加一个变量对象。对with语句来说,会将指定对象添加到作用域链中。对catch语句来说,会创建一个新的变量对象,其中包含的是被抛出的错误对象的声明。 9.JavaScript中没有块级作用域,因此if语句中的变量声明会添加到当前的执行环境中。在使用for语句时尤其要牢记这一差异,例如: ~~~ for (var i=0; i <10; i++) { doSomething(i) } alert(i); // 10 ~~~ 10.***优化内存占用的最佳方式,就是为执行中的代码只保留必要的数据。一旦全局对象、全局对象属性以及循环引用变量的引用不再有用,最好通过将其值设置为null来释放其引用--这个做法叫做解除引用。这一做法适用于大多数全局变量和全局对象的属性***。如下面这个例子所示: ~~~ function creatPerson(name) { var localPerson = new Object(); localPerson.name = name; return localPerson; } var globalPerson = creatPerson(‘Ken’); globalPerson = null; //在不使用它的时候手工为它解除引用。 ~~~ 11.基本类型值在内存中占据固定空间大小,因此被保存在栈内存中;引用类型的值是对象,保存在堆内存中。