美文网首页
高级任务2

高级任务2

作者: dengpan | 来源:发表于2017-05-23 14:06 被阅读52次

    1、apply、call 、bind有什么作用,什么区别?

    • apply语法--->fun.apply(thisArg[, argsArray]);thisArg是函数fun在运行时指定的this值;[argsArray]是一个数组或者类数组对象,其中的数组元素将作为单独的参数传给 fun 函数
    var value = 100;
    function fn(a,b){
        console.log(this.value + a + b);
    }
    fn(1,2);//103
    //apply()
    var obj = {
        value: 200
    };
    fn.apply(obj,[1,2]);//此时的this是obj,那么value值为200
    
    • call语法--->fun.call(thisArg[, arg1[, arg2[, ...]]]);thisArg是函数fun在运行时指定的this值;arg1,arg2是参数列表
    var value = 100;
    function fn(a,b){
        console.log(this.value + a + b);
    }
    fn(1,2);//103
    
    //call()
    var obj = {
        value: 200
    };
    fn.call(obj,1,2);//此时的this是obj,那么value值为200,结果为203
    
    • bind语法--->fun.bind(thisArg[, arg1[, arg2[, ...]]]);当绑定函数被调用时,该参数会作为原函数运行时的 this 指向,当使用new操作符调用绑定函数时,该参数无效;arg1, arg2当绑定函数被调用时,这些参数将置于实参之前传递给被绑定的方法
    var obj = {
        name: 'Byron',
        fn : function(){
            console.log(this);
        }
    };
    var obj2 = {
        name: 'obj2'
    };
    var fn2 = obj.fn.bind(obj2);//this指向obj2
    fn2();
    
    • 区别:
    • call()的第二个参数是一个参数列表,apply()的第二个参数是一个数组或类数组对象
    • bind()方法返回的仍然是一个函数,可以不立即执行,还可以在调用的时候再进行传参;而call()和apply()则是立即执行改变了this的函数

    2、以下代码输出什么?

    var john = { 
      firstName: "John" 
    }
    function func() { 
      alert(this.firstName + ": hi!")
    }
    john.sayHi = func
    john.sayHi()
    
    //对象的方法调用,this指向调用方,输出的结果为John: hi!
    

    3、下面代码输出什么,为什么?

    func() 
    function func() { 
      alert(this)
    }
    
    //函数调用,this指向的是window,输出结果为object Window
    

    4、下面代码输出什么?

    document.addEventListener('click', function(e){
        console.log(this); 
        setTimeout(function(){
            console.log(this);
        }, 200);
    }, false);
    
    //第一个this,指向绑定事件源DOM对象,输出结果是#document
    //第二个this,指向全局对象window,输出结果是windows
    

    5、下面代码输出什么,why?

    var john = { 
      firstName: "John" 
    }
    
    function func() { 
      alert( this.firstName )
    }
    func.call(john)
    
    //call调用,this指向call的第一个参数,这里是john,输出结果是John
    

    6、以下代码有什么问题,如何修改?

    var module= {
      bind: function(){
        $btn.on('click', function(){
          console.log(this) //this指什么
          this.showMsg();
        })
      },
      
      showMsg: function(){
        console.log('饥人谷');
      }
    }
    
    
    //这里的this指的是绑定事件的$btn,指不到module,this.showMsg()将不会实现
    //修改代码如下
    var module= {
      bind: function(){
        var that = this;
        $btn.on('click', function(){
          console.log(that);
          that.showMsg();
        })
      },
      
      showMsg: function(){
        console.log('饥人谷');
      }
    }
    
    

    7、有如下代码,解释Person、 prototype、proto、p、constructor之间的关联

    function Person(name){
        this.name = name;
    }
    Person.prototype.sayName = function(){
        console.log('My name is :' + this.name);
    }
    var p = new Person("若愚")
    p.sayName();
    
    /*关联如下
    p是Person的一个实例
    p.__proto__ === Person.prototype
    p.__proto__.constructor === Person
    Person.prototype.constructor === Person
    Person.prototype.__proto__ === Object.prototype
    Object.prototype.constructor === Object
    */
    

    8、上例中,对对象 p可以这样调用 p.toString()。toString是哪里来的? 画出原型图?并解释什么是原型链

    • toString()是从原型Object里面继承的
    • 原型图如下所示:


      原型图.png
    • 原型链--->JavaScript 对象有一个指向一个原型对象的链。当试图访问一个对象的属性时,它不仅仅在该对象上搜寻,还会搜寻该对象的原型,以及该对象的原型的原型,依此层层向上搜索,直到找到一个名字匹配的属性或到达原型链的末尾

    9、对String做扩展,实现如下方式获取字符串中频率最高的字符

    var str = 'ahbbccdeddddfg';
    var ch = str.getMostOften();
    console.log(ch); //d , 因为d 出现了5次
    
    • 实现代码如下:
                //对String做扩展,实现如下方式获取字符串中频率最高的字符
                var str = 'ahbbccdeddddfg';
    
                String.prototype.getMostOften = function(){
                    var rawStr = this.toString(),
                        length = this.length,
                        obj = {};
                    var biggest = {
                        str: '',
                        count: 0
                    };
                    for(var index = 0; index < length; index++){
                        var val = rawStr[index];
                        if(obj[val]){
                            obj[val] += 1;
                        }else{
                            obj[val] = 1;
                        }
                        if(obj[val] > biggest.count){
                            biggest.count = obj[val];
                            biggest.str = val;
                        }
                    }
                    return biggest; 
                };
    
                var ch = str.getMostOften();
                console.log(ch); //d , 因为d 出现了5次
    

    10、instanceOf有什么作用?内部逻辑是如何实现的?

    • instanceof--->语法:object instanceof constructor,instanceof 运算符用来检测 constructor.prototype 是否存在于参数 object 的原型链上,如果存在则返回true;否则false
    • 内部逻辑如下所示:
                //a instanceof b
               function _instanceof(a,b){
                   var aProto = a.__proto__;
                   var result = false;
                   do{
                       if(aProto === b.prototype){
                           result = true;
                           break;
                       }else{
                           aProto = aProto.__proto__;
                       }
                   }while(aProto)
                   return result;
               }
    

    11、继承有什么作用?

    • 继承可以直接使用另一个对象的属性和方法
    • 优化代码结构和对象关系
    • 优化内存空间

    12、下面两种写法有什么区别?

    //方法1
    function People(name, sex){
        this.name = name;
        this.sex = sex;
        this.printName = function(){
            console.log(this.name);
        }
    }
    var p1 = new People('饥人谷', 2)
    
    //方法2
    function Person(name, sex){
        this.name = name;
        this.sex = sex;
    }
    
    Person.prototype.printName = function(){
        console.log(this.name);
    }
    var p1 = new Person('若愚', 27);
    
    //方法1是将printName()作为构造函数的方法,在实例化的时候,每次都要创建printName(),作为新对象的私有属性
    //方法2是将printName()作为构造函数原型上的方法,在实例化的时候,p1可以调用,其它的实例也可以来调用,是作为共享的方法,可以优化内存空间
    

    13、 Object.create有什么作用?兼容性如何?

    • 作用:Object.create() 方法使用指定的原型对象和其属性创建了一个新的对象,如下代码
                var a = {
                    name: 'a'
                };
                var b = Object.create(a);//b.__proto__ === a
    
    • 兼容性如下图


      兼容性

    14、hasOwnProperty有什么作用? 如何使用?

    • 作用:hasOwnProperty() 检查该属性是否是其自有属性,而不是在原型链上找到的
    • 使用如下:
                var a = {
                    name: 'a'
                };
                a.hasOwnProperty('name');//true
                a.hasOwnProperty('toString');//false
                a.hasOwnProperty('valueOf');//false
    

    15、如下代码中call的作用是什么?

    function Person(name, sex){
        this.name = name;
        this.sex = sex;
    }
    function Male(name, sex, age){
        Person.call(this, name, sex);    //这里的 call 有什么作用
        this.age = age;
    }
    /*
    调用Person这个函数,将它的this替换成Male实例化时产生的新对象,使该对象拥有name、sex
    
    */
    

    16、补全代码,实现继承

    function Person(name, sex){
        // todo ...
    }
    
    Person.prototype.getName = function(){
        // todo ...
    };    
    
    function Male(name, sex, age){
       //todo ...
    }
    
    //todo ...
    Male.prototype.getAge = function(){
        //todo ...
    };
    
    var ruoyu = new Male('若愚', '男', 27);
    ruoyu.printName();
    
    • 代码如下
               function Person(name,age){
                    this.name = name;
                    this.age = age;
                }
                Person.prototype.getName = function(){
                    console.log('my name is ' + this.name);
                };
    
                function Male(name,age,sex){
                    Person.call(this,name,age);
                    this.sex = sex;
                }
    
                Male.prototype = Object.create(Person.prototype);
                //手动更改Male.prototype的constructor
                Male.prototype.constructor = Male;
    
                // 在继承函数之后写自己的方法,否则会被覆盖
                Male.prototype.getSex = function(){
                    console.log(this.sex);
                }
    
                var male = new Male('若愚',27,'男');
    

    版权声明:本教程版权归邓攀和饥人谷所有,转载须说明来源!!!!

    相关文章

      网友评论

          本文标题:高级任务2

          本文链接:https://www.haomeiwen.com/subject/jxsvxxtx.html