this-原型链-继承

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

  • function.prototype.bind()方法用于将函数体内的this绑定到某个对象,然后返回一个新函数。
    function Count() {
      this.count = 1
    }
    Count.prototype.doing = function () {
      console.log(this.count + 100)
    }

    var obj = {
      count: 200
    }

    var a = new Count().doing.bind(obj)//把obj的this绑定到bind()函数上,也就是doing函数
    console.log(a())
  • function.prototype.call()
    函数实例的call方法,可以指定函数内部this的指向(即函数执行时所在的作用域),然后在所指定的作用域中,调用该函数。
var obj = {}
var a = function() {
  console.log(this)
}
a()//指向window
a.call(obj)//指向obj
var b = Math.max.call(null,1,3,5,7,3,11)//输出11
  • function.prototype.apply()
    apply方法的作用与call方法类似,也是改变this指向,然后再调用该函数。唯一的区别就是,它接收一个数组作为函数执行时的参数
  var c = Math.max.apply(null,[1,3,5,7,3,11])//输出11

问题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] 由于函数名提升,所以不会是undefined,函数内部的this指向全局window

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

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

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

var john = { 
  firstName: "John" 
}

function func() { 
  alert( this.firstName )
}
func.call(john)//输出john,call把func函数执行的作用域call到john对象上

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

var module= {
  bind: function(){
    $btn.on('click', function(){
      console.log(this) //this指什么
      this.showMsg();
    })
  },
  
  showMsg: function(){
    console.log('饥人谷');
  }
}
var module= {
  bind: function(){
    $btn.on('click', function(){
      console.log(this) //this指什么,这里的this指向$btn
      this.showMsg();
    }.bind(module))//这里加一个bind,把函数作用域bind到module即可
  },
  
  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 instanceof Person === true
 //p是原型Person的一个实例,拥有Person原型链上的属性和方法
p.__proto__ === Person.prototype
Person.prototype.constructor === p.__proto__.constructor

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

this-原型链-继承_第1张图片
image.png
  • p先在自身找toString没有找到,然后去p.proto找还是没有找到,又去p.proto.proto里面找,然后找到。
  • 每个对象都有一个私有属性(称之为 [[Prototype]]),它持有一个连接到另一个称为其 prototype 对象(原型对象)的链接。该 prototype 对象又具有一个自己的原型,层层向上直到一个对象的原型为 null。

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

   var str = 'ahbbccdeddddfg';
    String.prototype.getMostOften = function () {
      var strArr = [].slice.apply(this)
      var obj = {}
      var maxTimes = 0
      var valueOfMaxTimes
      strArr.forEach(function (letter, idx) {
        if (obj[letter]) {
          obj[letter] += 1
        } else {
          obj[letter] = 1
        }
      });
      console.log(obj)
      for (var key in obj) {
        console.log(key)
        if (obj[key] >= maxTimes) {
          maxTimes = obj[key]
          valueOfMaxTimes = key
        } else {
          return '出现次数最多的字母是:' + valueOfMaxTimes + '\n' + '出现次数最多的字母的次数是:' + maxTimes + '次'
        } 
      }
    }
    var ch = str.getMostOften();
    console.log(ch); //d , 因为d 出现了5次

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

  • instanceof运算符返回一个布尔值,表示指定对象是否为某个构造函数的实例
    *由于instanceof对整个原型链上的对象都有效,因此同一个实例对象,可能会对多个构造函数都返回true。
var d = new Date();
d instanceof Date // true
d instanceof Object // 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每次创建一个实例就会重写一次printName 方法,方法2每次创建实例会共享一个printName 方法,不会再次去创建

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

  • Object.create() 方法会使用指定的原型对象及其属性去创建一个新的对象。
  • 兼容性:Object.create是ES5方法,IE9以下无效
  • 用 Object.create实现类式继承
    function Person(name, age) {
      this.name = name;
      this.age = age;
    }
    Person.prototype.sayName = function() {
      console.log(this.name)
    }

    function Male(name,age,sex) {
      this.sex = sex
      Person.apply(this,arguments)//使用apply方法技术Person属性
    }
    Male.prototype = Object.create(Person.prototype)//使用Object.create()方法继承Person的方法
    Male.prototype.constructor = Male
    var man = new Male('Jack',18,'男')
    man.sayName()

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

*对象实例的hasOwnProperty方法返回一个布尔值,用于判断某个属性定义在对象自身,还是定义在原型链上。

  • hasOwnProperty方法是JavaScript之中唯一一个处理对象属性时,不会遍历原型链的方法。
Math.hasOwnProperty('min')
//true
Math.hasOwnProperty('abs')
//true
Math.hasOwnProperty('toString')

问题15:如下代码中call的作用是什么?

function Person(name, sex){
    this.name = name;
    this.sex = sex;
}
function Male(name, sex, age){
    Person.call(this, name, sex);    //这里的 call把person的作用域改为Male
    this.age = age;
}

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

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

    Person.prototype.getName = function () {
      console.log('姓名:' + this.name)
    };

    function Male(name, sex, age) {
      this.age = age
      Person.apply(this, arguments)
    }
    Male.prototype = Object.create(Person.prototype)
    Male.prototype.constructor = Male
    Male.prototype.getAge = function() {
      console.log(this.age)
    }
   
    var ruoyu = new Male('若愚', '男', 27);
    ruoyu.getAge();

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