札早早

导航

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了

 

posted on 2018-01-16 21:21  札早早  阅读(122)  评论(0)    收藏  举报