美文网首页
this 原型链 继承

this 原型链 继承

作者: 饥人谷_有点热 | 来源:发表于2017-07-03 13:20 被阅读0次

    this 相关问题

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

    apply、call 、bind这三个方法都可以用来改变函数this的指向。

    bind返回一个新函数,并且使函数内部的this为传入的第一个参数
    示例:

    this.x = 9; 
    var module = {
      x: 81,
      getX: function() { return this.x; }
    };
    
    module.getX(); // 返回 81
    
    var retrieveX = module.getX;
    retrieveX(); // 返回 9, 在这种情况下,"this"指向全局作用域
    
    // 创建一个新函数,将"this"绑定到module对象
    // 新手可能会被全局的x变量和module里的属性x所迷惑
    var boundGetX = retrieveX.bind(module);
    boundGetX(); // 返回 81
    

    callapply比较相似,在指定this的同时,可以传递参数。唯一区别在于call()方法接受的是若干个参数的列表,而apply()方法接受的是一个包含多个参数的数组。
    示例:

    function greet() {
      var reply = [this.person, 'Is An Awesome', this.role].join(' ');
      console.log(reply);
    }
    
    var i = {
      person: 'Douglas Crockford', role: 'Javascript Developer'
    };
    
    greet.call(i); // Douglas Crockford Is An Awesome Javascript Developer
    
    var numbers = [5, 6, 2, 3, 7];
    var max = Math.max.apply(null, numbers);
    //max=7
    

    2.以下代码输出什么?

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

    输出结果:弹窗 John:hi!

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

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

    [Object window],因为直接调用函数func(),this将会被指向window

    4.下面代码输出什么

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

    点击之后先输出:#document 延时200ms后再输出window

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

    var john = { 
      firstName: "John" 
    }
    
    function func() { 
      alert( this.firstName )
    }
    func.call(john)
    

    输出 John,因为call 的第一个参数为指定this的指向,传入john相当于讲func中的this直线了john

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

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

    当bind被调用,$btn被点击的时候,会报错showMsg() undefined。
    主要原因是on的回调函数里的this被指向了被点击的元素本身,想要正常执行需要修改成

    var module= {
      bind: function(){
        $btn.on('click', function(){
          console.log(this) //this指什么
          this.showMsg();
        }.bind(this))
      },
      
      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();
    

    构造函数Person,他的prototype里有一个sayName方法。实例化一个Person 赋值给p,p的proto包含了Person.prototype里的方法和属性,以及constructor,constructor被指向Person,因为p是由Person这个构造函数创建的,相当于Person是p的模板。

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

    image.png

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

    String.prototype.getMostOften=function(){
            var string = this,
                info={},
                get_obj,
                get_max;
    
            get_obj=(function(){
                
                var obj={};
                for(var i = 0;i<string.length;i++){
                if (obj[string[i]]) {
                    obj[string[i]] = obj[string[i]] + 1;
                }else{
                    obj[string[i]] =1;
                }
                }
                return obj;
            })(string);
            
            
            // console.log(obj);
    
            get_max=(function(){
                var max = 0;
                for(var i in get_obj){
                if(get_obj[i]>max){
                    max = get_obj[i];
                }
            }
            return max;
            })();
            
            for(var i in get_obj){
                if (get_obj[i]===get_max) {
                    info[i] = get_obj[i]
                }
            }
            // console.log(max);
            return info;
        }
    var str = 'ahbbccdeddddfg';
    var ch = str.getMostOften();
    console.log(ch); //d , 因为d 出现了5次
    

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

    instanceof 运算符用来测试一个对象在其原型链中是否存在一个构造函数的 prototype 属性。
    示例:

    示例

    instanceof的内部就是实现了如下内容:

    s instanceof Person
    //首先
    s.__proto__ === Person.prototype //false
    
    //得到结果是false,接下去再比较
    s.__proto__.__proto__ ===Person.prototype //true
    
    

    继承相关问题

    11.继承有什么作用?

    子类可以不重写父类的属性和方法,直接调用父类的属性和方法。同时可以拓展出自己的方法和属性。
    举个例子:

    1
    上图中的 s既可以调用自己prototype中的方法,也可以调用父类中prototype中的方法。

    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);
    

    通过方法一创建的p1单独拥有一个printnName方法,而通过方法二创建的p1也可以调用printName方法 但是自己不拥有该方法,而是存在与原型链里由Person创建出来的实例公有的方法。

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

    Object.create()方法使用指定的原型对象和其属性创建了一个新的对象。它接受两个参数,如果当参数只有一个的时候,它的作用和object()方法的行为是相同的。第二个参数的用法

    目前支持该方法的浏览器有IE9+,Firefox4+, Safari5+,Opera12+ 和Chrome。也就是说IE 6 7 8 不支持。不过可以使用下面这个方法来hack 实现:


    借用new来实现继承

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

    使用hasOwnProperty()方法可以检测一个属性是存在于实例中,还是存在于原型中。

    示例:

     function Person(){
    
        }
        Person.prototype={
            name:'Jack',
            age:22,
            sex:'male',
            sayName:function(){
                console.log(this.name)
            }
        }
    
        var p1 = new Person();
        var p2 = new Person();
    
        p1.name = 'Greg';
        console.log(p1.name);                   //Greg ---来自实例
        console.log(p1.hasOwnProperty('name')); //true
    
    
        console.log(p2.name);                  //Jack ---来自原型
        console.log(p2.hasOwnProperty('name'));//false
    
        delete p1.name;
        console.log(p1.name);                  //Jack ---来自原型
        console.log(p1.hasOwnProperty('name'));//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 的属性

    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, sex) {
                this.name= name;
                this.sex = sex;
            }
    
            Person.prototype.printName = 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.printName();
    

    相关文章

      网友评论

          本文标题:this 原型链 继承

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