原型、原型链、原型继承

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();
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 官方中文版原文链接 感谢社区中各位的大力支持,译者再次奉上一点点福利:阿里云产品券,享受所有官网优惠,并抽取幸运大...
    HetfieldJoe阅读 3,024评论 4 14
  • 在JavaScript中,原型链作为一个基础,老生长谈,今天我们就来深入的解读一下原型链。 本章主要讲的是下面几点...
    Devinnn阅读 1,418评论 1 6
  • 博客内容:什么是面向对象为什么要面向对象面向对象编程的特性和原则理解对象属性创建对象继承 什么是面向对象 面向对象...
    _Dot912阅读 1,454评论 3 12
  • 1. apply、call 、bind有什么作用,什么区别? call ,apply的作用:调用一个函数,传入函数...
    Rising_suns阅读 403评论 0 0
  • 20岁,大学二年级,一个美好的时光,有贴心的朋友,没有男朋友,也并不打算去拥有,一个人的自己,我习惯的很好,很合拍...
    cocohuang阅读 208评论 0 3