js面试题汇总
var a=0; function aa(a){ alert(a) var a=3 } aa(5) alert(a) //5,0 在函数体内,参数a的优先级高于变量a
var a=0;
function aa(a){
alert(a)
var a=3
}
aa(5)
alert(a)
***************************************
var a=0;
function aa(a){
alert(a)
a=3
}
aa(5)
alert(a)
//5,0 在函数体内,执行alert(a)和a=3,修改的的并不是全局变量a,而是参数a
***************************************
var a=0;
function aa(a){
alert(a)
var a=3
alert(a)
}
aa(5)
//5,3
**************************************
var a=0;
function aa(a){
alert(a)
a=3
alert(a)
}
aa()
alert(a)
//underfind 3 0
//首先,参数优先级高于全局变量,由于没传参数,所以是underfind
//a=3,实际上修改的时形参a的值,并不是全局变量a,往下alert(a)也是形参a
//最后的alert(a),你懂的
**************************************************
function foo1()
{
return {
bar: "hello"
};
}
function foo2()
{
return
{
bar: "hello"
};
}
var a=foo1();
var b=foo2();
console.log(a) //Object {bar: "hello"}
console.log(b) //underfind
//仔细看就知道了
************************************************
var fullname = 'John Doe';
var obj = {
fullname: 'Colin Ihrig',
prop: {
fullname: 'Aurelio De Rosa',
getFullname: function() {
return this.fullname;
}
}
};
console.log(obj.prop.getFullname()); //Aurelio De Rosa
var test = obj.prop.getFullname; //John Doe
console.log(test());
解释:
obj.prop.getFullname() 直接调用的是obj里面的prop的函数! 所以这时候函数fullname就是为Aurelio De Rosa
而在var test = obj.prop.getFullname,只是把这个函数赋值到test。相当于
var test = function(){
return this.fullname;
}
题5:call() 和 apply()
现在让你解决前一个问题,使最后的console.log() 打印 Aurelio De Rosa。
回答
该问题可以通过强制使用 call() 或者 apply() 改变函数上下文。在下面我将使用call(),但在这种情况下,apply()会输出相同的结果:
console.log(test.call(obj.prop));
**********************************************************8
var f = function g(){ return 23; }; typeof g();//报错 这是一个名字是 g的function expression,然后又被赋值给了变量 f。 这里的函数名 g和被其赋值的变量 f有如下差异: 函数名 g不能变动,而变量 f可以被重新赋值 函数名 g只能在函数体内部被使用,试图在函数外部使用 g会报错的 *************************************************** (function(x){ delete x; return x;//1 })(1); delete操作符可以从对象中删除属性,正确用法如下: delete object.property delete object['property'] delete操作符只能作用在对象的属性上,对变量和函数名无效。也就是说 delete x是没有意义的。 你最好也知道, delete是不会直接释放内存的,她只是间接的中断对象引用 **************************************************** var y = 1, x = y = typeof x; x;//"undefined" 我们试图分解上述代码成下面两步: var y = 1; //step 1 var x = y = typeof x; //step 2 第一步应该没有异议,我们直接看第二步 赋值表达式从右向左执行 y被重新赋值为 typeof x的结果,也就是 undefined x被赋值为右边表达式( y = typeof x)的结果,也就是 undefined *************************************************** (function f(f){ return typeof f();//"number" })(function(){ return 1; }); 直接上注释解释: (function f(f){ //这里的f是传入的参数function(){ return 1; } //执行的结果自然是1 return typeof f(); //所以根据问题一的表格我们知道,typeof 1结果是"number" })(function(){ return 1; }); (function f(f){ return typeof f();//"number" })(function(){ return 1; }); 直接上注释解释: (function f(f){ //这里的f是传入的参数function(){ return 1; } //执行的结果自然是1 return typeof f(); //所以根据问题一的表格我们知道,typeof 1结果是"number" })(function(){ return 1; }); return typeof f; 返回function ************************************** var foo = { bar: function() { return this.baz; }, baz: 1 }; (function(){ return typeof arguments[0]();//"undefined" })(foo.bar); 这里你可能会误以为最终结果是 number。向函数中传递参数可以看作是一种赋值,所以 arguments[0]得到是是真正的 bar函数的值,而不是 foo.bar这个引用,那么自然 this也就不会指向 foo,而是 window了。 ****************************************** var foo = { bar: function(){ return this.baz; }, baz: 1 } typeof (f = foo.bar)();//"undefined" 这和上一题是一样的问题, (f = foo.bar)返回的就是 bar的值,而不是其引用,那么 this也就指的不是 foo了。 ***************************** var f = (function f(){ return '1'; }, function g(){ return 2; })(); typeof f;//"number" 逗号操作符 对它的每个操作对象求值(从左至右),然后返回最后一个操作对象的值 所以 (function f(){ return '1'; }, function g(){ return 2; })的返回值就是函数 g,然后执行她,那么结果是 2;最后再 typeof 2,根据问题一的表格,结果自然是 number ************************************* (function f(){ function f(){ return 1; } return f();//2 function f(){ return 2; } })(); 通过 function declaration声明的函数甚至可以在声明之前使用,这种特性我们称之为hoisting。于是上述代码其实是这样被运行环境解释的: (function f(){ function f(){ return 1; } function f(){ return 2; } return f(); })(); ******************************************* (function f(){ function f(){ return 1; } return f();//2 function f(){ return 2; } })(); 通过 function declaration声明的函数甚至可以在声明之前使用,这种特性我们称之为hoisting。于是上述代码其实是这样被运行环境解释的: (function f(){ function f(){ return 1; } function f(){ return 2; } return f(); })(); *************************************** function f(){ return f; } new f() instanceof f;//false 当代码 new f()执行时,下面事情将会发生: 一个新对象被创建。它继承自 f.prototype 构造函数 f被执行。执行的时候,相应的传参会被传入,同时上下文( this)会被指定为这个新实例。 new f等同于 new f(),只能用在不传递任何参数的情况。 如果构造函数返回了一个“对象”,那么这个对象会取代整个 new出来的结果。如果构造函数没有返回对象,那么 new出来的结果为步骤1创建的对象, ps:一般情况下构造函数不返回任何值,不过用户如果想覆盖这个返回值,可以自己选择返回一个普通对象来覆盖。当然,返回数组也会覆盖,因为数组也是对象。 于是,我们这里的 new f()返回的仍然是函数 f本身,而并非他的实例 *********************************************** with (function(x, undefined){}) length;//2 with语句将某个对象添加的作用域链的顶部,如果在 statement中有某個未使用命名空间的变量,跟作用域链中的某個属性同名,則這個变量将指向這個属性值。如果沒有同名的属性,则将拋出 ReferenceError异常。 OK,现在我们来看,由于 function(x, undefined){}是一个匿名函数表达式,是函数,就会有 length属性,指的就是函数的参数个数。所以最终结果就是 2了
浙公网安备 33010602011771号