J31 javaScript基础练习题

163 阅读7分钟

1.提前声明没有赋值变量默认值是undefined

  • 1.EC(G)变量提升 var a;

  • 2.声明全局变量,存放到VO(G)

  • 3.声明的全局变量,会给全局对象GO(window)也设置一个相同的属性window.a,

  • 4.后期不论是全局对象还是全局变量,一个改变,另外一个也会跟着改变(映射机制)

    console.log(a); //=>undefined var a = 12; a = 13; console.log(a); //=>13

2.报错:没有任何变量声明

  • 在全局中,输出一个变量,首先看其是否为全局变量[VO(G)],如果不是,则继续观察其是否为全局对象对象[GO->window]中的一个属性,如果也不是则报错:变量未定义错误 Uncaught ReferenceError: a is not defined

    console.log(a);//=>is not a defined a = 13; console.log(a);

3.给全局对象GO存储值

window.a = 13;
//=>在全局对象GO中设置一个属性

console.log(a); 
//=>13   a是GO中的一个属性  => window.a

a = 14; //=>window.a=14

console.log(a); //=>14

4.LET 和 VAR 的区别:

  • 1.基于LET/CONST/CLASS/IMPORT等ES6中的方式创建变量,不存在变量提升(也就是只有VAR和FUNCTION有变量提升机制)

    console.log(a); //=>Uncaught ReferenceError: Cannot access 'a' before initialization //=>let声明的 a未初始化前不能使用 let a = 12; a = 13; console.log(a);

5.计算

console.log(a, b, c);//=>undefined*3
var a = 12,
    b = 13,
    c = 14;
function fn(a) {
    console.log(a, b, c);//=>10 13 14
    a = 100;
    c = 200;
    console.log(a, b, c);//=>100 13 200
}
b = fn(10);//=>函数执行完没有写return返回结果是unedefined
console.log(a, b, c);//=>12 undefined 200

6.计算题(数组)

var ary = [12, 23];//=>AAAFFF000 [100,23]
function fn(ary) {//=>AAAFFF111
    console.log(ary);//AAAFFF111
    ary[0] = 100;
    ary = [100];//=>AAAFFF222 [0]
    ary[0] = 0;
    console.log(ary);[0]
}
fn(ary);
console.log(ary);[100,23]

7、计算 (函数不释放问题被占用)

  • 一般函数执行,形成的上下文,在函数执行完都会出栈释放,以此保证内存优化;但是如果当前上下文中的某些东西,被上下文之外的变量等占用了,则不能出栈释放,此上下文之前存储的私有变量也就被保存下来了

  • 作用域链只和函数创建的时候[scope]有关系,创建的时候就已经决定了未来作用域链的指向;和在哪里执行的没有关系

    var i = 0; function A() { var i = 10; function x() { console.log(i); } return x; } var y = A(); y();//=>10 function B() { var i = 20; y(); } B();//=>10

8.计算(函数)

var a=1;
var obj ={
   "name":"tom"
}
function fn(){
   var a2 = a;
   obj2 = obj;
   a2 =a;
   obj2.name =”jack”;
}
fn();
console.log(a);//=>1
console.log(obj);//=>{name:"jack"}

9.计算(函数)

var x = 100,
	y = 100;
    function fn() {
    // 私有上下文 EC(FN)
    //   AO(FN)  y=200
    var y = 200;
    console.log(x); //=>100 全局变量
    x=1000;         //=>把全局的x修改为1000
    console.log(y); //=>200 私有变量
    //console.log(z); //=>Uncaught ReferenceError: z is not defined
    z = 300; //=>window.z=300
    }
fn();
console.log(window.z); //=>300 

10 计算(函数)

var a = 1;
function fn(a) {
	console.log(a);
	var a = 2; 
	function a() {}
	console.log(a);
}
fn(a); 
console.log(a);

分析:
/*
 * EC(G)全局上下文
 *   VO(G)全局变量对象 
 *      var a;
 *      function fn(a){...};  fn[[scope]]=EC(G)
 */
var a = 1; //=>全局a=1
function fn(a) {
/*
 * 私有上下文 EC(FN) 
 *    AO(FN)私有变量对象
 *       a = 1
 *         = 函数
 *         = 2
 * SCOPE-CHAIN:<EC(FN),EC(G)>
 * 形参赋值: a=1
 * 变量提升:
* var a;(没用了,因为此时AO中有a了)
* a = 函数;  此处的操作,又把AO中的a的值修改为函数了
 */

	console.log(a); //=>函数a
	var a = 2; //=>a=2  让私有的a改为2
	function a() {}
	console.log(a); //=>2
}
fn(a); 
//=>全局函数fn执行,传递实参“全局变量a的值”
//=>fn(1)
console.log(a); //=>1

11 计算(函数 )

console.log(a);
var a=12; 
function fn(){
    console.log(a);
    var a=13; 
}
fn();   
console.log(a); 

 /!*
 * EC(G)全局上下文
 *    var a;
 *    function fn(){...};
 *!/
console.log(a); //=>undefined
var a=12; //=>全局变量a=12
function fn(){
	/!*
	 * EC(FN)私有上下文
	 *    var a; 
	 *!/
    console.log(a); //=>undefined
    var a=13; //=>私有变量a=13
}
fn();   
console.log(a); //=>全局变量a的值是12 

12 变量提升与函数

console.log(a);
var a=12;
function fn(){
console.log(a);  
a=13;
}
fn();
console.log(a);

/!*
 * EC(G)全局上下文
 *    var a;
 *    function fn(){...};
 *!/
console.log(a); //=>undefined
var a=12;//全局a=12
function fn(){
	/!*
	 * EC(FN)私有上下文
	 *!/
    console.log(a); 
//=>不是自己的私有变量,找到的是EC(G)中的全局变量  12
    a=13;//全局a=13
}
fn();
console.log(a); //=>13

13 计算(函数没声明)

console.log(a);
a=12;
function fn(){
    console.log(a);
    a=13;
}
fn();
console.log(a);

 /!*
 * EC(G)全局上下文
 *   function fn(){...};
 *!/
console.log(a);//=>Uncaught ReferenceError: a is not defined
a=12;
function fn(){	
    console.log(a);
    a=13;
}
fn();
console.log(a);

15 计算(变量提升与函数)

var a=10,b=11,c=12;
function test(a){
     a=1;
     var b=2; 
     c=3; 
}
test(10);
console.log(a); 
console.log(b); 
console.log(c);  

/!*
* EC(G)全局上下文
*   var a;  var b;  var c; 
* function test(){...};   test[[scope]]=EC(G);
*!/

var a=10,b=11,c=12; //全局a=10 b=11 c=12
function test(a){
/!*
*EC(TEST)私有上下文 
*(形参和在函数体中声明过的变量是私有变量)
*    a = 10
*    b   
* SCOPE-CHAIN:<EC(TEST),EC(G)>
* 形参赋值:a=10
* 变量提升:var b;
*!/
 a=1; //私有a=1
 var b=2; //私有b=2
 c=3; //全局c=3
}
test(10);
console.log(a);  //=>10
console.log(b);  //=>11
console.log(c);  //=>3

16 条件判断(变量提升)

if (!("a" in window)) { 
}
console.log(a);

/!*
* EC(G)全局上下文
*  var a;  
*  声明一个全局变量 VO(G)
*  给GO(window)设置一个属性 window.a
*!/
if (!("a" in window)) { // "a" in window => undefined=>!false=>true
	var a = 1;
}
console.log(a); //=>undefined

17 计算(函数形参赋值)

var a = 4;
function b(x, y, a) {
	console.log(a);
	arguments[2] = 10;
	console.log(a);
}
a = b(1, 2, 3);
console.log(a);

/!*
 * EC(G)全局上下文
 *   var a;
 *   function b(x,y,a){...};  b[[scope]]=EC(G);
 *!/
var a = 4; //全局a=4
function b(x, y, a) {
/!*
 * EC(B)私有上下文
 *   x=1
 *   y=2
 *   a=3
 *
 * 1.SCOPE-CHAIN:<EC(B),EC(G)>
 * 2.初始化THIS
 * 3.初始化ARGUMENTS = { 0:1, 1:2, 2:3, length:3 }
 * 4.形参赋值:分别给x/y/a赋值
 * 5.变量提升
 * 6.代码执行
 *
 * 在JS非严格模式下,ARGUMENTS和形参变量存在映射机制(因为都是用来存储传递的实参信息的
 * //=>,ARGUMENTS不管是否定义形参都会存在,定义形参后,不仅形参可以获取传递的值
 * //=>,ARGUMENTS中也存储了传递的值,此时两者有映射机制了)
 *   第一个形参变量 映射 ARGUMENTS[0]
 *   第二个形参变量 映射 ARGUMENTS[1]
 *   ...
 *   映射:后期不论是形参变量更改值,还是ARGUMENTS更改每一项的值,互相都会跟着改变
 *!/

console.log(a); //=>3
arguments[2] = 10;
//=>把ARGUMENTS索引为2(也就是第三个传递的实参)修改为10,由于映射机制,形参a的值也会跟着变为10
console.log(a); //=>10
}
a = b(1, 2, 3);
//把b函数执行,分别传递1,2,3三个实参给函数,把函数执行的返回值(只看RETURN)赋值给全局变量a  
=>全局a=undefined,因为函数没有写return返回值
console.log(a); //=>undefined 

18 计算(函数形参赋值arguments集合)

function fn(x, y, z) {
	console.log(x, y, z, arguments);
	arguments[0] = 100; 
	y = 200; 
	arguments[2] = 300;
	console.log(x, y, z, arguments);
}
fn(10, 20, 30); 

 function fn(x, y, z) {
	console.log(x, y, z, arguments);
	// => x=10  y=20  z=30
	// => arguments = [10,20,30]

	arguments[0] = 100; //[100,20,30] x=100
	y = 200; //y=200 [100,200,30]
	arguments[2] = 300; //[100,200,300] z=300

	console.log(x, y, z, arguments);
	// => x=100  y=200  z=300
	// => arguments = [100,200,300]
}
fn(10, 20, 30); 

19 计算(函数中的arguments在严格模式下是不起作用的)

"use strict";
function fn(x) {
console.log(x); 
arguments[0] = 100;
console.log(x);
}
fn(10); 

"use strict";
//=>使用JS严格模式(JS最开始位置加)
function fn(x) {
console.log(x); //=>10
arguments[0] = 100;
//严格JS模式下,映射机制不存在,此处只是把arguments修改了,x是不会跟着改变的
console.log(x); //=>10
}
fn(10); 

20 计算提(自执行函数)

var foo = 'hello'; 
(function (foo) {
console.log(foo);
var foo = foo || 'world'; 
console.log(foo);
})(foo); 
console.log(foo); 

/!*
 * EC(G)全局上下文
 *   var foo;
*!/
var foo = 'hello'; //全局foo='hello'
(function (foo) {
/!*
* EC(AN)私有上下文
*    foo = 'hello' 
*此处是私有变量,和全局不是一个,但是因为是把全局值给他的,所以此时两个变量的值是一样的,
*但是不是相同的变量
*
* SCOPE-CHAIN:<EC(AN),EC(G)>
* 初始THIS/ARGUMENTS
* 形参赋值:给foo赋值
* 变量提升:var foo;(已经声明了)
* 代码执行
*!/
console.log(foo); //=>'hello'
var foo = foo || 'world'; //foo='hello' || 'word'='hello'
console.log(foo); //=>'hello'
})(foo); //自执行函数执行,把全局foo的值作为实参传递给函数  ...('hello')
console.log(foo); //=>'hello'