JS笔试题

1、考察实参argument、函数运行时的作用域

<script>
    	function sum() {			
				if (arguments.length == 2) {
					return arguments[0] + arguments[1];
				} else if (arguments.length == 1) {
					var first = arguments[0];//2
					return function(second) {
						return first + second;
					};
				}
			}
			console.log(sum(2,3));//5			
			console.log(sum(2)(3));//5
    /*
    解析:
    argument代表实参类数组
    当sum(2,3)时,arguments.length == 2,返回arguments[0] + arguments[1]=>2+3=5
    当sum(2)(3)时,调用sum函数后返回的函数再调用;
    sum(2)=>function(second){return first + second};
    再调用返回的函数,传入3,second=3,first在函数中没有,到外部作用域查找;
    因为函数是写在函数中的,函数调用时的作用域是看函数写在那个位置(此处考察函数运行时的作用域)
    所以first=2 first+second=2+3=5
    
    */
</script>

2、考察this

<script>
    var User = {
			      count: 1,
			      getCount: function() {
			          return this.count
			      }
			  }
			  var fn = User.getCount //让fn引用User.getCount
			  console.log(fn());  //fn()可写为window.fn(),调用者为window
                                  //调用返回结果为window.count=>indefined

            /*
            易错:
            认为getCount函数的调用者为User,内部的this代表User,但是只是这里并未调用,
            只是把User的属性让fn引用,this是看是谁调用。
            真正的调用者是是隐式的window,fn()可写为window.fn()
            
            */

</script>

3、关于作用域

<script>
			function fun(n, o) {
				console.log(o)
				return {
					fun: function(m) {
						return fun(m, n);
					}
				};
			}
			var a = fun(0);
			a.fun(1);
			a.fun(2);
			a.fun(3);
			var b = fun(0).fun(1).fun(2).fun(3);
			
			var c = fun(0).fun(1);
			c.fun(2);
			c.fun(3);
        /*
            解析:
关于a:
            fun(0)=>
            执行过程:fun(n,o){
                var n,o
                n=0
                o=undefined
                console.log(o)//打印undefined
                return { fun: function(m) {return fun(m, n);}};
            }
            a={ fun: function(m) {return fun(m, n);}};
            a.fun(1)=>
             function(m) {
              var m = 1;
				return fun(m, n);先调用函数,再返回值(补充: fun: function()这种形式是无法直接通过fun()调用,要通过对象.fun());
            此时调用外部的fun函数,fun(m,n)=>m,n先取值再传入,m=1,n在函数内未存在。到上一级作用域查找n=0;
            }
            fun(n, o) {
                var n,o
                n=1;
                o=0
				console.log(o)//打印0
				return {fun: function(m) {return fun(m, n);}};
			
            }
             a.fun(1)= {fun: function(m) {return fun(m, n);}};

             a.fun(2)=>
             function(m) {
              var m = 2;
				return fun(m, n);先调用函数,再返回值
            此时调用外部的fun函数,fun(m,n)=>m,n先取值再传入,m=2,n在函数内未存在。到上一级作用域查找n=0;
            }
            fun(n, o) {
                var n,o
                n=2;
                o=0
				console.log(o)//打印0
				return {fun: function(m) {return fun(m, n);}};
			
            }
             a.fun(2)= {fun: function(m) {return fun(m, n);}};

            a.fun(3)=>
             function(m) {
              var m = 3;
				return fun(m, n);先调用函数,再返回值
            此时调用外部的fun函数,fun(m,n)=>m,n先取值再传入,m=3,n在函数内未存在。到上一级作用域查找n=0;
            }
            fun(n, o) {
                var n,o
                n=3;
                o=0
				console.log(o)//打印0
				return {fun: function(m) {return fun(m, n);}};
			
            }
             a.fun(3)= {fun: function(m) {return fun(m, n);}};

关于b:
             fun(0).fun(1).fun(2).fun(3)=>
            全局作用域:[fun(0)]{
                function fun(n, o) {
                    var n,o;
                    n=0;
                    o=undefined;
				console.log(o) //打印undefined
				return { //fun(0)返回值 
					fun: function(m) {
						return fun(m, n);
					}
				};
                [fun(0).fun(1)]调用这个返回值:{
                    function(m) {
                        var m;
                        m=1
						return fun(m, n); ==>调用全局作用域下的fun,m、n先取值,m=1,n=0
                        得到:{  
					fun: function(m) {
						return fun(m, n);
					}
				};
                [fun(0).fun(1).fun(2)]调用这个返回值:{
                         function(m) {
                        var m;
                        m=2
						return fun(m, n); ==>调用全局作用域下的fun,m、n先取值,m=2,n=1
                        得到:{  
					fun: function(m) {
						return fun(m, n);
					}
				};
                   [fun(0).fun(1).fun(2).fun(3)]调用这个返回值:{
                         function(m) {
                        var 3;
                        m=3
						return fun(m, n); ==>调用全局作用域下的fun,m、n先取值,m=3,n=2
                        得到:{  
					fun: function(m) {
						return fun(m, n);
					}
				};  
                    }
                }
            }
            m=1时调用的 function fun(n, o) {
                    var n,o;
                    n=1;
                    o=0;
				console.log(o) //打印0
				return { //fun(0).fun(1)返回值 
					fun: function(m) {
						return fun(m, n);
					}
				};
                
             m=2时调用的 function fun(n, o) {
                    var n,o;
                    n=2;
                    o=1;
				console.log(o) //打印1
				return { //fun(0).fun(1).fun(2)返回值 
					fun: function(m) {
						return fun(m, n);
					}
				};

            m=3时调用的 function fun(n, o) {
                    var n,o;
                    n=3;
                    o=2;
				console.log(o) //打印2
				return { //fun(0).fun(1).fun(2).fun(3)返回值 
					fun: function(m) {
						return fun(m, n);
					}
				};
             b={  fun: function(m) {return fun(m, n);}

关于c:
            全局作用域:[fun(0)]{
                function fun(n, o) {
                    var n,o;
                    n=0;
                    o=undefined;
				console.log(o) //打印undefined
				return { //fun(0)返回值 
					fun: function(m) {
						return fun(m, n);
					}
				};
                [fun(0).fun(1)]调用这个返回值:{
                    function(m) {
                        var m;
                        m=1
						return fun(m, n); ==>调用全局作用域下的fun,m、n先取值,m=1,n=0
                        得到:{  
					fun: function(m) {
						return fun(m, n);
					}
				};
                }
                }
            }
        }
          m=1时调用的 function fun(n, o) {
                    var n,o;
                    n=1;
                    o=0;
				console.log(o) //打印0
				return { //fun(0).fun(1)返回值 
					fun: function(m) {
						return fun(m, n);
					}
				};
                
            c={  fun: function(m) {return fun(m, n);}
            
            c.fun(2)=>
            此时function fun(n, o) {
                    var n,o;
                    n=1;
                    o=0;
				console.log(o) //打印0
				return { //fun(0).fun(1)返回值 
					fun: function(m) {
						return fun(m, n);
					}
				};
            运行 c.fun(2):
            function(m) {
              var m = 2;
				return fun(m, n);先调用函数,再返回值
            此时调用外部的fun函数,fun(m,n)=>m,n先取值再传入,m=2,n在函数内未存在。到上一级作用域查找n=1;
        }
        function fun(n, o) {
                    var n,o;
                    n=2;
                    o=1;
				console.log(o) //打印1
				return { //c.fun(2)返回值 
					fun: function(m) {
						return fun(m, n);
					}
				};
            运行 c.fun(3):
            function(m) {
              var m = 3;
				return fun(m, n);先调用函数,再返回值
            此时调用外部的fun函数,fun(m,n)=>m,n先取值再传入,m=3,n在函数内未存在。到上一级作用域查找n=1;
        }
        function fun(n, o) {
                    var n,o;
                    n=3;
                    o=1;
				console.log(o) //打印1
				return { //c.fun(3)返回值 
					fun: function(m) {
						return fun(m, n);
					}
				};
        
        */

</script>

4、标识符的隐式提升和作用域

<script>
    		var num = 5;
			function func1() {
				var num = 3;
				var age = 4;// 调用func3后,age=6
				function func2() {
					console.log(num);//unf
					var num = 'ivan';

					function func3() {
						age = 6;
					}
					func3();
					console.log(num);// 'ivan'
					console.log(age);//6
				}
				func2();
			}
			func1();
            /*
            解析:
            1、函数不调用则不运行,先声明一个num赋值为5,再调用func1函数
            2、声明局部变量num和age分别赋值为3和4,再调用func2
            
            3、func2内部情况
            function func2() {
                    var num;  标识符隐式提升
                    function func3() { 函数提前声明
						age = 6;
					}
					console.log(num);在这个函数中,此时num只是声明了,但未赋值,打印undefined
					 num = 'ivan'; //为num赋值为'ivan'
					func3();
                    调用func3,{age = 6;为age赋值,func3函数无age,到上级作用域查找}
					console.log(num);// 'ivan'
					console.log(age);// func2中无age,到fun1中寻找,上面经过调用func3,将age                                的修改为6
                                    //打印结果为6
				}
            */
</script>

5、对象的知识

<script>
    	function changeObjectProperty(o) {
				o.siteUrl = "http://www.csser.com/";
				o = new Object();
				o.siteUrl = "http://www.popcg.com/";
				return o
			}
			var CSSer = new Object();
            //CSSer引用一个新创建的空对象		
			var re=changeObjectProperty(CSSer);	
            //调用changeObjectProperty函数,把这个对象当实参传入函数,并赋值给re
            /*
            changeObjectProperty函数执行过程:
            changeObjectProperty(o) {
                var o=CSSer //让o也引用CSSer这个对象引用的对象
          
				o.siteUrl = "http://www.csser.com/";
                 //为这个对象添加一个siteUrl属性,并赋值为"http://www.csser.com/"
				o = new Object();
                o引用一个新的对象;
				o.siteUrl = "http://www.popcg.com/";
                为o的新对象添加一个siteUrl属性,并赋值为"http://www.csser.com/"
				return o //返回的是新创建的这个属性
			}
            */		
			console.log(CSSer.siteUrl);//"http://www.csser.com/"
			console.log(re.siteUrl)//"http://www.csser.com/"
			re=null;//防止内存泄漏
</script>

6、对象知识

<script>
            var x = 8;
			var objA = {
				x: 'good',
				y: 32 //=>5
			}

			function add(x, y) {
				console.log(x.y + y);//8
			}

			function fn(x, y) {
				x.y = 5;
				y(x, 3);
			}
			fn(objA, add);
			console.log(objA);//{x:"good",y:5}
                /*
            解析:
            调用fn函数,将objA对象和add函数作为实参传入。
            fn函数执行过程:
            function fn(x, y) {
                var x,y
                x={
				x: 'good',
				y: 32
			};
                y=function(x, y){
				console.log(x.y + y);//8
			}
				x.y = 5;
            //将y属性的值改为5,因为x引用的是objA对象,所以外部的objA对象也发生了改变
				y(x, 3);
            //调用函数,先取x的值=>y(8,3)
            function(x, y){
                var x,y
                x=8;
                y=3;
				console.log(x.y + y)//这里的x是对象,到上级作用域查找
                                    //5+3=8
			}
            
            最后打印objA//{x:"good",y:5}
            */
</script>

7、对象的知识

<script>
			var obj1 = new Object();
            //声明obj1标识符引用{}
			obj1.name = 'zjzhome';
            //为obj1引用的对象添加一个name属性,赋值为'zjzhome'
			var obj2 = obj1;
            //让obj2也引用这个对象
			console.log(obj2.name);//因为是同一个对象  打印'zjzhome'
			obj1.name = 'zjz'; //修改name的值
			console.log(obj2.name);//'zjz'
</script>

8、运算符

		<script>
			var a = '' + 3;
            //字符串与数字相加转换为字符串拼接
			var b = 4;
			console.log(typeof a); //"string"
			console.log(a + b); //"34"
			console.log(a - b); //-1  数值类型的字符串可以跟数字减法运算
			console.log({} - b) //NaN  
			//number:   NAN 200 100 10.2 Infinity


			var foo = "11" + 2 + "1";
			console.log(foo); //"1121"
			console.log(typeof foo); //"string"


			var foo1 = "11" + 2 + 1;
            //只要有一个是字符串全部都会进行字符串拼接
			console.log(foo1)//1121

			var foo2 = "11" + 2 * 2;
            //先进行乘法运算,它的优先级高
			console.log(foo2)//114
		</script>

9、考察函数运行时作用域

	<script>
			var name = 'laruence';

			function echo() {
				console.log(name);
			}

			function env() {
				var name = 'eve';
				echo();//'laruence';
			}
			env();
            //调用env函数,
            function env() {
				var name = 'eve';//声明局部变量name,赋值为'eve'
				echo();//调用echo函数,打印name,'laruence'
                       //echo是写在全局作用域下的,它的作用域不在env内,所以打印的是全局变量name
			}
			
		</script>

10、考察细心

        <script>
			a = new Array(2, 3, 4, 5, 6);
			sum = 0;
			for (i = 1; i < a.length; i++) //i是从1开始的,取不到2
				sum += a[i]; //结果为3+4+5+6
			console.log(sum);//18
		</script>

11、考察作用域

<script>
var f = true;
			if (f === true) {
				var a = 10;
			}

			function fn() {
				var b = 20;
				c = 30;
			}
			fn();
			console.log(a); //10
			console.log(b); //b为局部变量,全局作用域下无法直接访问,代码报错
			console.log(c); //代码报错后,后面的代码不再执行
</script>

12、考察 this 作用域 隐式声明提升 原型 符号优先级

<script>	
			function Foo() {
				getName = function() {
					console.log(1);
				}
				return this;
			}
			Foo.getName = function() {console.log(2)}
			Foo.prototype.getName = function() {console.log(3)}
			var getName = function() {console.log(4)}
			function getName() {console.log(5)}
			Foo.getName();
			getName();
			Foo().getName();
			getName();
			new Foo.getName();
			new Foo().getName();
			new new Foo().getName();

        /*
        预编译:
            var getName
            function Foo() {
				getName = function() {
					console.log(1);
				}
				return this;
			}
            function getName() {console.log(5)}
            Foo.getName = function() {console.log(2)}
            //为Foo添加一个属性getName,值为function() {console.log(2)}
            Foo.prototype.getName = function() {console.log(3)}
            getName = function() {console.log(4)}
            Foo.getName(); // 2
            //取Foo的getName属性,然后再调用  
			getName();// 4  调用全局作用域下的getName函数,从下往上找就近优先
            // getName = function() {console.log(4)}调用这个函数
			Foo().getName(); //1
            //先调用Foo函数,为getName赋值,本函数内无getName,到上一级作用域寻找,为getName从新赋值,此时getName = function() {console.log(4)} =>getName = function() {console.log(1)} 
            //然后返回this对象,代表window,Foo().getName()=>window.getName()
            //调用function() {console.log(1)}
			getName(); //1
            //调用全局作用域下的getName函数,此时getName = function() {console.log(1)}
			new Foo.getName(); //2
            //根据优先级
            //先访问Foo的成员,再new一个函数(new带参优先级大于函数调用优先级)
            //new (Foo.getName)()=>1、创建一个空对象 2、调用Foo.getName函数 3、返回这个空对象
			new Foo().getName(); // 1
            //根据优先级 从左往右 
            //((new Foo()).getName)()  (访问成员优先级大于函数调用)
            //1、创建一个空对象 2、调用Foo函数,将getName = function() {console.log(1);}
            //3、函数然回创建的这个空对象
            //4、此时表达式为{__proto__:{getName:function() {console.log(3)}} }.getName() 此时对象内无这个函数到原型链上查找
            //5、调用function() {console.log(3)}
			new new Foo().getName();//3
            //根据优先级
            //new ((new Foo()).getName)()
            //1、创建一个对象{} 2、调用Foo函数,将getName = function() {console.log(1);}
            //3、函数然回创建的空对象
            //4、此时表达式为new ({__proto__:{getName:function() {console.log(3)}} }.getName)()
            //5、创建一个对象{} 6、调用{__proto__:{getName:function() {console.log(3)}} }.getName函数 打印3
            //7、返回一个空函数
        */
</script>

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值