原型、原型链、原型继承

this 相关问题
问题1: apply、call 、bind有什么作用,什么区别

作用: 给函数指定this。是用来指定上下文的
区别: bind:bind()会创建一个新的函数,将其中的值,作为原来函数的this。例如xx.bind(obj)中,obj为xx的this 。将函数体中的this绑定到对象上,然后返回一个新的函数。
call: call()是使用一个指定的this值和相关参数的前提下调用函数或方法。接受的参数为若干个参数的列表。简单来说,就是可以指定函数内部this的指向(即在此函数执行时所在的作用域),让在所指定的作用域中,调用该函数。就是var obj={};function fn(){ return this;};fn.call(obj),call改变this的指向。让fn的this是指向obj的,在obj的作用域中运行
apply: apply()效果同call(),不过其接受的参数为数组。

问题2: 以下代码输出什么?

 var john = { 
        firstName: "John" 
          }
    function func() { 
        alert(this.firstName + ": hi!")
    }
    john.sayHi = func
    john.sayHi()  ==》方法调用
    输出:  
              john hi!

问题3: 下面代码输出什么,为什么

func() 
function func() { 
  alert(this)
}        ==》函数调用
输出: window,因为在function中的this,没有找到对象,所以继续向外找,
            而function的外部环境为window,则输出window

问题4:下面代码输出什么

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

输出:document 
           window

问题5:下面代码输出什么,why

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

输出:john

原因:call()函数为func函数绑定了this=john

call()函数将func函数的this指向了john,并且func的执行在john的作用域中

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

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

问题:console.log出来的是$btn 饥人谷 ;//不知道。
当调用module.bind()的时候。this.showMsg()无法调用。因为这里的this指向了$btn。所以将this.showMsg()改为module.showMsg();
或是通过嫁接方式;var that=this;that.showMsg();
原型链相关问题

问题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的构造对象,而Person是构造函数。 在new的过程中,p的-proto-指向 Person,因为Person的原型上绑定一个方法:sayName,即constructor下有sayName。所以p 拥有属性:name;和方法sayName()。

问题8: 上例中,对对象 p可以这样调用 p.toString()。toString是哪里来的? 画出原型图?并解释什么是原型链。
来自上一级的原型。
https://www.draw.io/#Hkomolei%2Ftry%2Fmaster%2FUntitled%20Diagram.xml
原型链:所有的对象都有-proto-这个属性,这个链接到另一个-proto-,像这样一个个-proto-相链接起来的样子,称为原型链。对于函数,则是prototype了。
问题9:对String做扩展,实现如下方式获取字符串中频率最高的字符

 var str = 'ahbbccdeddddfg';
 String.prototype.getMostOften =
  function () {
   // var str = 'ahbbccdeddddfg';
   var str=this;
    // console.log(this);
   var o = {};
   for (var i = 0; i < str.length; i++) {
   var char = str.charAt(i);
   if (o[char]) {
      o[char]++; //次数加1
    } else {
      o[char] = 1; //若第一次出现,次数记为1
    }
  }
  // console.log(o); //输出的是完整的对象,记录着每一个字符及其出现的次数
  //遍历对象,找到出现次数最多的字符的次数
  var max = 0;
  for (var key in o) {
    if (max < o[key]) {
      max = o[key]; //max始终储存次数最大的那个
    }
  }
  for (var key in o) {
    if (o[key] == max) {
      //console.log(key);
      // console.log("最多的字符是" + key);
      // console.log("出现的次数是" + max);
      return key;
    }
  }
}
var ch = str.getMostOften();
 console.log(ch);

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

作用: instanceof 运算符用来测试一个对象在其原型链中是否存在一个构造函数的 prototype 属性。
就是检测一个原型链上是否存在某个prototype。a.instanceof b.prototype :就是a的原型链中是否存在b.prototype;
实现逻辑:让其一层一层沿着原型链去查找,找到就return true;
继承相关问题

问题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是 绑定在People上。方法2的printName是绑定到原型上。在new多个实例的时候,方法2可以直接调用。在多次调用的时候可以优化内存空间。而方法1要多次写入。
同时方法2中要更改prototype的时候,其的每一个实例的printName都会改变。而方法1需要每个都是修改。

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

Object.create() 方法使用指定的原型对象和其属性创建了一个新的对象。简单来说就是可以手动的去指定对象的原型。创建一个新的对象,第一层的原型链指向对应的参数。
兼容性:支持各个浏览器。ie需要ie9以上。

问题14: hasOwnProperty有什么作用? 如何使用?

作用:看对象上的属性是属于自己的,还是从原型链继承来的。
使用:object.hasOwnPrototype(" 属性")

问题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;
}

作用:让Male继承Person中的属性。手动将this指向Person。就是将Person中的this引用到Male中。

问题16: 补全代码,实现继承

function Person(name, sex){
    // todo ...
    this.name=name;
    this.sex=sex;
}

Person.prototype.getName = function(){
    // todo ...
    console.log(this.name);
};    

function Male(name, sex, age){
   //todo ...
    Person.call(this,name,sex)
    this.age=age;
    //this.printName=function(){
      //    console.log(this.name)
      //}
      this.printName=Person.prototype.getName;
  }

  //todo ...
Male.prototype.getAge = function(){
  //todo ...
   console.log(this.age)
};

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;
    //this.printName=function(){
      //    console.log(this.name)
      //}
      //this.printName=Person.prototype.getName;
  }
  //todo ...  
Male.prototype=new Person() ; //继承:将一个对象的prototype指向要继承的对象即可
Male.prototype.getAge = function(){
//       todo ...
  console.log(this.age)
};
var ruoyu = new Male('若愚', '男', 27);
ruoyu.printName();

你可能感兴趣的:(原型、原型链、原型继承)