美文网首页
this_原型链_继承

this_原型链_继承

作者: mianmiani | 来源:发表于2017-06-10 21:05 被阅读0次

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

    fn.apply(context[,arguments])
    
    fn.call(context[,p1][,p2])
    
    fn.bind(context)()
    

    这三个方法的作用都是调用一个对象的一个方法,以另一个对象替换当前对象(即改变执行上下文也就是改变this的指向)apply和call除了传入参数一个为所有参数的集合数组,一个为分开传入参数之外没有区别,而bind的返回值是一个函数,也就是说没有立即被执行。

    以下代码输出什么?

    var john = { 
      firstName: "John" 
    }
    function func() { 
      alert(this.firstName + ": hi!")
    }
    john.sayHi = func
    john.sayHi()
    
    //输出John: hi!,因为对象john调用了函数func,所以此时的this为john对象
    

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

    func() 
    function func() { 
      alert(this)
    }
    //输出window对象,因为函数是在全局环境下执行的,此时的this为window对象
    

    下面代码输出什么

    document.addEventListener('click', function(e){
        console.log(this);   //这里输出document对象
        setTimeout(function(){
            console.log(this);   //这里输出window对象
        }, 200);
    }, false);
    

    下面代码输出什么,why

    var john = { 
      firstName: "John" 
    }
    function func() { 
      alert( this.firstName )
    }
    func.call(john)
    //输出John,因为.call方法将执行上下文改为了john对象,所以这里的this就是john对象
    

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

    var module= {
      bind: function(){
        $btn.on('click', function(){
          console.log(this)     //this指$btn对象
          this.showMsg();
        })
      },
      
      showMsg: function(){
        console.log('饥人谷');
      }
    }
    //修改为:
    var module= {
      bind: function(){
        var _this = this
        $btn.on('click', function(){
          console.log(this)     //this指$btn对象
          _this.showMsg();
        })
      },
      
      showMsg: function(){
        console.log('饥人谷');
      }
    }
    //或者
    var module= {
      bind: function(){
        $btn.on('click', function(){
          console.log(this)     //此时this指module对象
          this.showMsg();
        }.bind(this))
      },
    
      showMsg: function(){
        console.log('饥人谷');
      }
    }
    

    原型链相关问题

    有如下代码,解释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.__proto__.constructor === Person
    p.__proto__  ===  Person.prototype
    Person.prototype.constructor  ===  Person
    Person.prototype.__proto__ ==Object.prototype
    
    

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

    原型图
    原型链:
    JS在创建对象(不论是普通对象还是函数对象)的时候,都有一个叫做proto的内置属性,用于指向创建它的函数对象的原型对象prototype。
    以上面的例子为例:
    p.__proto__ == Person.prototype
    Person.prototype.__proto__ == Object.prototype
    Object.prototype.__proto__ == null
    

    从p.proto串联到null的的形式就叫做原型链。
    判断对象p是否有toString()方法时,首先从p.proto里面找方法,找不到时就到父级的原型里找,直到找到,当找到null还没找到时就会报错。

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

      var str = 'ahbbccdeddddfg';
      var ch = str.getMostOften();
      String.prototype.getMostOften = function () {
            var a = {};
            for(var i=0;i<this.length;i++){
                var b = this[i]
    
                if(a[b] == undefined){
                    a[b] = 1
                }else{
                    a[b] ++
                }
            }
            var max = 0;
            var arr = [];
            for(var key in a){
                if(a[key]>max){
                    max = a[key]
                    arr.push(key)
                }
            }
            return (arr[arr.length-1]+',因为'+arr[arr.length-1]+'出现了'+max+'次')
        }
    }
    console.log(ch); //d , 因为d 出现了5次
    

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

    判断对象是否为构造函数的实例,instanceOf会判断对象的.proto是否等于构造函数的原型,如果不等,再判断对象的proto.proto;直到null,如果都不等,则对象不是构造函数的实例。

    继承相关问题

    继承有什么作用?

    继承:利用原型链让一个引用类型继承另一个引用类型的方法和属性。
    能够大大减少工作量,不用重复的写代码,方便方法和属性的修改,并且可以覆盖父类的方法。

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

    //方法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);
    

    方法一将printName方法写在了构造函数内部,方法二将printName方法写在了构造函数的原型里。
    方法一在每生成一个新对象的时候都要运行一遍方法函数,而写在原型里提供给对象调用则大大减少了这方面的成本。

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

    Object.create方法使用指定的原型对象和其属性创建了一个新的对象。
    此方法可以实现继承

    a.prototype = Object.create(b.prototype)
    

    此方法在ie上兼容性表现较差,从ie9开始兼容

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

    hasOwnProperty方法会返回一个布尔值,指示对象是否具有指定的属性作为自身(不继承)属性。

    function A(){
    }
    var a = new A()
    a.sayName = function(){}
    a.hasOwnPrototype('sayName')   //true
    

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

    function Person(name, sex){
        this.name = name;
        this.sex = sex;
    }
    function Male(name, sex, age){
        Person.call(this, name, sex);    //这里的 call 有什么作用:继承Person的name和sex属性
        this.age = age;
    }
    

    补全代码,实现继承

    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;
    }
    
    Male.prototype = Object.create(Person.prototype)
    Male.prototype.constructor = Male
    Male.prototype.getAge = function(){
       console.log(this.age)
    };
    
    var ruoyu = new Male('若愚', '男', 27);
    ruoyu.getName();
    

    相关文章

      网友评论

          本文标题:this_原型链_继承

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