• call和apply的区别


    昨天和js大神谈js,他说要是他出题的话,就问apply和call的区别。。。

    现在整理一下,首先说apply和call的不同之处其实就是 方法传递的参数不同,(还有一个是性能方面的差别,apply的性能要差很多。)

    call( fun, arg1 , arg2 ,arg3...... ), 而apply只接受 两个参数 apply( fun , [ arg1 , arg2 ,arg3....])(以数组形式存储)

    两者的作用呢,都是变化上下文,所谓的上下文是指 对象的空间:

    var a = {
        o : 100,
        m : function (){
         console.log(this.o);
         var o = 200;
           }
        }    
    

      则变量o和函数m的上下文就是对象 a。

    注 :在JavaScript中,代码将总是有着某种形式的上下文(代码在其内部工作的 对象)

    上下文是通过变量this(号称魔法变量)工作。变量this总是引用代 码当前所在的那个对象。记住全局对象实际上是window对象的属性。这意味着即使是在全局上下文里,this 变量仍然引用一个对象。

    下面来举一些有点磨人的例子:

    (1)全局变量k

    var k = 200;
    var obj = {
        f : function() {
            console.log( k );
            k = 100;
        }
            
    }
    
    obj.f();    // 200 ,k为一个全局的变量,k的上下文是window
    

    (2 ) this.k,此处的this指代的对象是 obj,而在执行console.log(this.k)的时候,下一句k还没有定义,但是由于声明提前,所以k已经声明,所以不会报错,

    而是undefined(相当于在内存开了一个0字节的内存,也就是只是声明了一个变量,而没有给它赋值,则默认值)

    var k = 200;
    var obj = {
        f : function() {
            console.log( this.k );
            k = 100;
        }
            
    }
    
    obj.f();   // undefined
    

    (3) 自执行的函数,是一个自我封闭的区域,其中的this没有上下文,没有上下文默认为全局的window是其上下文。

    var k = 200;
    var o = {
        k : 100,
        m : (function()  {
         console.log(k);        //200
         console.log(this.k);   // 200
        } )()
    }
    
    o.m;
    

    其他一些问题:(好难)

    1.考的是函数中参数arguments的类型,arguments是参数的集合,是一个对象不是数组

    (function(){
        return typeof arguments;
    })()
    结果是: object

    2.命名函数表达式的函数名只对函数体内可见

    var f = function g(){ return 23; };
      typeof g();
    //根据标准,命名函数表达式的函数名只对函数体内可见
    //因此报错

    //Uncaught ReferenceError: g is not defined
    //at <anonymous>:3:3
    //at Object.InjectedScript._evaluateOn (<anonymous>:905:140)
    //at Object.InjectedScript._evaluateAndWrap (<anonymous>:838:34)
    //at Object.InjectedScript.evaluate (<anonymous>:694:21)

    3.参数是不可删除的

    (function(x){
        delete x;
        return x;
        })(1);
    结果是:1

    4.未赋值的变量默认为undefined

    var y = 1, x = y = typeof x;
        x;
    结果是:undefined
    //声明两个变量x与y,y最初赋为1,x没有赋值,默认赋给window的一个属性undefined,
    //因此typeof undefined为"undefined",最后x= y= "undefined"

    5.函数名被优先级更高的参数名覆盖了,内存覆盖了

     (function f(f){
        return typeof f();
        })(function(){ return 1; });
    //结果就是: typeof 1; 最终结果是: number
    //函数名被优先级更高的参数名覆盖了

    6.自执行函数的上下文,这个解释了自执行函数的上写文是window了

     var foo = { 
          bar: function() { return this.baz; }, 
          baz: 1
        };
        (function(){ 
          return typeof arguments[0]();
        })(foo.bar);
    结果是: undefined
    //我们把下面那个自动执行函数分解一下
    //var a = function(){
    //  return typeof arguments[0]();
    //};
    //a(foo.bar)
    //执行完arguments[0](),即得到this.baz
    //由于this变量在此绑定失效,它指向window,window有bax变量吗?
    //没有,返回"undefined"

    7.还是this指代的当前对象的变化

    var foo = {
          bar: function(){ return this.baz; },
          baz: 1
        }
        typeof (f = foo.bar)();
    结果是: undefined
    解释是:这个函数可以等价于:
    // window.f;
    // f = foo.bar;
    // f();
    //此时this指向的对象是window了,所以最后结果是undefined;

    8.内存中后赋值的会覆盖掉先赋值的(包括变量赋值和函数赋值哟)

     var f = (function f(){ return "1"; }, function g(){ return 2; })();
        typeof f;
    结果是 typeof 2 => number
    解释是: var a = ( 1,2,3 )
    a ; => 3
    函数赋值亦是这样,f先是赋值为f(),然后赋值为g().
    所以最后执行的是g函数

    9.这题好难。。。。理解

    var x = 1;
     if (function f(){}) {
       x += typeof f;
     }
    x ;
    结果是: 1undefined
    //函数声明只能裸露于全局作用域下或位于函数体中
    //从句法上讲,它们不能出现在快中,例如不能出现在if,while,或for语句中,因为块只能包含语句。
    因此if()中的f函数不能当做函数声明,当成表达式使用
    //可能是预编译阶段做了如下处理:
    //if ( xxx = function(){} )
    //根据第2条,命名函数表达式的函数名只对函数体内可见,所以是找不到f的。

    10.typeof undefined = "undefined" //string型的

      var x = [typeof x, typeof y][1];
         typeof typeof x;
    结果是: string
    x数组其实是: [ "undefined" , "undefined" ]

    11.这题其实简单,就是要看清楚{有几层

     (function(foo){
          return typeof foo.bar;
        })({ foo: { bar: 1 } });
    结果是: undefined
    看到这样复杂的可以这样解释:
    var a = {foo:{bar:1}}
    (function( foo ) {
    return typeof foo.bar
    })(a);
    a中的属性只有foo

    12.声明提升

    (function f(){
          function f(){ return 1; }
          return f();
          function f(){ return 2; }
        })();
    结果: 2

    13.这题就不是很明白,应该是instanceof对象是否是特定类的一个实例

    function f(){ return f; }
     new f() instanceof f;
    结果是:false
    解释是: 由于函数f会返回自身,这个new就形同虚设
    如果f的形式为function f(){ return this;}或function f(){}就不一样

    14.函数的length就是指它形参的长度,with就是一个读写器,题意就是取出函数的length属性

    with (function(x, undefined){}) length;
    结果是:2

      

      

      

      

      

      

      

      

      

      

      

      

      

     

  • 相关阅读:
    适配器模式(PHP实现)
    php基础设计模式 注册树模式、工厂模式、单列模式
    mongodb数据库操作--备份 还原 导出 导入
    mongodb 非 admin 库 认证登陆失败 原因(百度好多都 是渣)db.addUser() 请走开。
    css3 标题超过长度自动省略号
    html5新增及废除属性
    HTML5 改良的 input 元素的种类
    SQLite学习笔记(十一)&&虚拟机原理
    SQLite使用(三)&&核心API使用
    SQLite使用(二)&&数据类型
  • 原文地址:https://www.cnblogs.com/shixiaomiao/p/4762820.html
Copyright © 2020-2023  润新知