面向对象03 相关问题

作者: IT男的成长记录 | 来源:发表于2017-03-15 23:07 被阅读0次

    this相关问题

    1.apply、call、bind

    • apply()和call()都是在特定的作用域中调用函数,实际上等于设置函数体内this对象的值
      • apply()方法接收两个参数:一个是在其中运行函数的作用域,另一个是参数数组
      • call()方法接收的第一个参数时在其中运行函数的作用域,剩余的都是传递给函数的参数
      • 两者的真正作用是:扩充函数赖以运行的作用域
    window.color = "red";
    var o = {color: "blue"};
    function sayColor(){
        alert(this.color);
    }
    sayColor();
    sayColor.call(this); // red
    sayColor.call(o); //blue
    
    • bind():创建一个函数的实例,其this值会被绑定到传给bind()函数的值
    window.color = "red";
    var o = {color: "blue"};
    function sayColor(){
        alert(this.color);
    }
    var objectSayColor = sayColor.bind(o);
    objectSayColor(); // blue
    

    sayColor()调用bind()并传入对象o,创建了objectSayColor()函数,objectSayColor()函数的this值等于o,因此即使是在全局作用域中调用这个函数,也会看到"blue"

    2.以下代码输出什么?

    var john = { 
      firstName: "John" 
    }
    function func() { 
      alert(this.firstName + ": hi!")
    }
    john.sayHi = func
    john.sayHi()
    

    输出: John: hi!

    原因:sayHi()是作为john对象的方法调用的,因此this等于john对象.

    3.下面代码输出什么,为什么

    func() 
    function func() { 
      alert(this)
    }
    

    输出: window
    原因: 当执行func()时,其实它是作为Window对象的方法调用的,因此,this指的是window

    4.下面代码输出什么,为什么

    document.addEventListener('click', function(e){
        console.log(this);
        setTimeout(function(){
            console.log(this);
        }, 200);
    }, false);
    

    输出:
    document
    window

    原因: 事件处理函数中的this指的是其对应的dom对象,setTimeout中的this指的是window

    5.下面代码输出什么,为什么

    var john = { 
      firstName: "John" 
    }
    
    function func() { 
      alert( this.firstName )
    }
    func.call(john)
    
    • 输出: John
    • 原因: func.call()中传入了对象john,因此将func中this的值设置为了对象john

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

    var module= {
      bind: function(){
        $btn.on('click', function(){
          console.log(this) //this指什么
          this.showMsg();
        })
      },
      
      showMsg: function(){
        console.log('饥人谷');
      }
    }
    
    • 问题:事件处理函数中的this指的是该事件处理函数绑定的对象,即$btn,因此该对象没有showMsg()方法

    • 修改:在bind内部设置一个变量将this保存下来,这样在事件处理函数中使用该变量来调用showMsg方法

    var module= {
      bind: function(){
        var _this = this;
        $btn.on('click', function(){
          console.log(this) //this指什么
          _this.showMsg();
        })
      },
      
      showMsg: function(){
        console.log('饥人谷');
      }
    }
    

    原型链相关问题

    1.有如下代码,解释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("yanxin")
    p.sayName();
    

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

    原型链: 每个构造函数都有一个原型对象,原型对象都包含一个指向构造函数的指针,而实例都包含一个指向原型对象的内部指针.如果让原型对象等于另一个类型的实例,则原型对象将包含一个指向另一个原型的指针,相应的另一个原型也包含着一个指向另一个构造函数的指针.如此层层递进,就构成了实例与原型的链条,即原型链

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

    var str = 'ahbbccdeddddfg';
    var ch = str.getMostOften();
    
    String.prototype.getMostOften = function(){
        var hash = {};
        var mostOften = '';
        var count = 0;
        for(var i = 0; i< this.length; i++){
            if(!hash[this[i]]){
                hash[this[i]] = 1;
            }else {
                hash[this[i]]++;
            }
            if(hash[this[i]] > count){
                count = hash[this[i]];
                mostOften = this[i];
            }
        }
        return mostOften;
    }
    console.log(ch); //d , 因为d 出现了5次
    

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

    • 使用 object instanceof constructor
    • 作用:检测 constructor.prototype 是否存在于参数 object 的原型链上
    • 每个实例都包含一个指向原型对象的内部指针(proto),通过该指针可以找到其原型链上的所有内容,因此可以检测 constructor.prototype 是否存在于参数 object 的原型链上

    继承相关:

    1.继承有什么作用?

    • 继承可以简化对事物的描述:子类可以继承父类的属性,因此只需定义子类特有的属性即可
    • 通过继承可以提高代码的重用性:父类提供的方法,子类通过继承可以直接使用

    2.下面两种写法有什么区别

    //方法1
    function People(name, sex){
        this.name = name;
        this.sex = sex;
        this.printName = function(){
            console.log(this.name);
        }
    }
    var p1 = new People('yanxin', 2)
    
    //方法2
    function Person(name, sex){
        this.name = name;
        this.sex = sex;
    }
    
    Person.prototype.printName = function(){
        console.log(this.name);
    }
    var p1 = new Person('yanxin', 27);
    
    • 方法1:将printName方法放在了构造函数中,但是由于使用了匿名函数,因此每个实例的printName方法都是不同的(尽管功能相同,但每个实例的printName方法都会占用内存空间),并没有实现代码的复用
    • 方法2:将printName方法放在了Person的原型对象中,当Person的实例调用printName方法时,会沿着原型链,找到Person的原型对象,使用Person的原型对象中的printName方法,因此,尽管每个Person实例都可以调用printName方法,但是这些printName方法都指的是Person的原型对象中的printName方法.实现了代码的复用

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

    • Object.create的作用如下面的代码,即创建一个新的构造函数,然后将传入的对象作为这个构造函数的原型对象,最后返回一个由该构造函数创建的一个新实例.
    function object(o){
        function F() {};
        F.prototype = o;
        return new F();
    }
    
    • 由于Object.create()在ECMAScript5中新增的,因此在低版本浏览器中并不支持,例如IE 6,7,8

    4.hasOwnProperty有什么作用? 如何使用?

    • hasOwnProperty这个方法可以用来检测一个对象是否含有特定的自身属性(和方法),该方法会忽略掉那些从原型链上继承到的属性(和方法)。

    • 使用: obj.hasOwnProperty(prop),prop指要检测的属性,可以是字符串或者Symbol,返回一个true或false。

    5.如下代码中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;
    }
    
    
    • 通过call()方法,在(未来将要)新创建的Male实例的环境下调用了Person构造函数,这样就会在新Male对象上执行Person()函数中定义的所有对象初始化代码,Male的每个实例都会具有自己的name和sex属性.

    6.补全代码,实现继承

    function Person(name, sex){
        this.name = name;
        this.sex = sex;
    }
    
    Person.prototype.getName = function(){
        console.log(this.name);
    }; 
    
    function Male(name, sex, age){
        Person.call(this, name, sex);
        this.age = age;
    }
    
    function inheritPrototype(subType, superType){
        // 创建了一个只包含superType原型对象内容的对象
        var prototype = Object.create(superType.prototype);
        prototype.constructor = subType;
        subType.prototype = prototype;
    }
    
    inheritPrototype(Male, Person);
    Male.prototype.getAge = function(){
        console.log(this.age);
    };
    
    var yanxin = new Male('闫鑫', '男', 22);
    yanxin.getName();
    

    相关文章

      网友评论

        本文标题:面向对象03 相关问题

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