this 原型链 继承

作者: SHININGJACK | 来源:发表于2017-12-27 00:23 被阅读0次

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

首先说明,这三者的主要用途都是为了:调用函数时,使用你指定的this

  1. apply

调用一个函数,为其指定this,参数以数组形式传入。

  1. call

调用一个函数,为其指定this,分别提供参数。

  1. bind

返回一个函数,并为其指定this
如(当全局环境变量不是window的时候,直接运行sum可能返回NaN):

var value = 2
function sum(a, b) {
//   console.log(this.value + a + b, 1)
  return this.value + a + b
}

//直接调用
sum(3, 4) // 2 + 3 + 4 = 9

//apply 指定 this,参数以数组形式传递
var obj1 = {
  value: 5
}
sum.apply(obj1, [3, 4])  // 5 + 3 + 4 = 12

//call 指定 this,分别提供参数

var obj2 = {
  value: 6
}

sum.call(obj2, 3, 4)    // 6 + 3 + 4

//bind 指定 this,返回一个新的函数
var obj3 = {
  value: 7
}

var newSum = sum.bind(obj3)
newSum(3,4)    // 7 + 3 + 4

二、 以下代码输出什么?

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

输出John: hi!,因为这里的sayHijohn调用的,所以this指向的就是join对象。

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

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

在浏览器运行时,thiswindow,因此,代码运行后,会弹窗显示window对象。

四、下面代码输出什么

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

第一个thisdocument,因为事件绑定自动把this指向为对应元素。第二个thiswindow,因为匿名函数的执行是在window全局下的。

五、下面代码输出什么,why

var john = { 
  firstName: "John" 
}

function func() { 
  alert( this.firstName )
}
func.call(john)

弹窗显示John,因为call指定了thisjohn对象。

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

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

上面的this指向调用事件的 DOM 元素,要想让this指向对象本身,可以先保存原来的this,如:

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

Person是构造函数,prototype是构造函数的共有属性。pPerson的实例,该实例有__proto__对象指向Person.prototypeconstructor表示该实例的构造器,指向Person

p.__proto__.constructor === Person.prototype.constructor === Person

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

toStringp原型链上Object构造函数的方法。

Object 示例

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

题目

var str = 'ahbbccdeddddfg';
var ch = str.getMostOften();
console.log(ch); //d , 因为d 出现了5次

解决

String.prototype.getMostOften = function(){
  let data = this
  let obj = {}
  for (let i = 0; i < data.length; i++) {
    if (obj[data[i]]) {
      obj[data[i]]++
    } else {
      obj[data[i]] = 1
    }
  }

  let max = 0
  let maxStr = ''
  for (let it in obj) {
    if (obj[it] > max) {
      max = obj[it]
      maxStr = it
    }
  }

  return maxStr
}

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

instanceOf用来判断一个对象是是否是一个构造函数的实例。内部是通过判断instance.__proto__ === Object.prototype是否相同来实现的,假如当前不相等,就会根据原型链往上找,instance.__proto__.__proto__ === Object.prototype,直到null,找到就返回true,否则为false

十一、继承有什么作用?

继承可以复用父类的属性和方法,无需重写,同时可以在子类上进行扩展。继承既可减少代码又易于扩展。

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

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

第一种写法,每次new出来的实例,都会产生新的属性和方法,占用过多不必要的内存。第二种写法,每次new出来的实例,会产生新的属性,但方法都在共有的属性原型链(prototype)上,节省内存。

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

Object.create()方法会使用指定的原型对象及其属性去创建一个新的对象,实现类式继承。如:

Student.prototype = Object.create(Person.prototype);
兼容性

十四、hasOwnProperty 有什么作用? 如何使用?

hasOwnProperty()方法会返回一个布尔值,指示对象自身属性中是否具有指定的属性(是自身属性,不包含prototyep)。

function Person(){
  this.name = 'jack'
}

Person.prototype.commonName = 'Person'

var a = new Person()

console.log(a.hasOwnProperty('name'))

十五、如下代码中 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;
}

这里的callthis指向当前的Male,实现继承Person

十六、补全代码,实现继承

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

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

function Male(name, sex, age) {
  //todo ...
  Person.call(this, name, sex)
  this.age = age
}

Male.prototype = Object.create(Person.prototype)
Male.prototype.constructor = Male

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

Male.prototype.printName = function(){
  console.log('My name is ' + this.getName() + '.')
}

var ruoyu = new Male('若愚', '男', 27);
ruoyu.printName();

相关文章

  • 继承

    原型链直接继承 原型链直接继承prototype 原型链继承_prototype属性 继承_构造函数绑定

  • js中的实现继承的几种方式

    大纲:原型链借用构造函数组合继承原型式继承寄生式继承寄生组合式继承 1、原型链: 什么是原型链? 原型链的基本思想...

  • JavaScript 原型、原型链与原型继承

    原型,原型链与原型继承 用自己的方式理解原型,原型链和原型继承 javascript——原型与原型链 JavaSc...

  • js基础之实现继承的几种方式

    js 实现继承的方式有: 原型链继承; 构造函数继承; 组合继承(原型链继承 + 构造函数继承)(最常用);(原型...

  • es5的部分继承以及es6的class

    一、JavaScript常用的原型继承方式 原型链继承 2,构造函数继承(对象冒充继承) 3,组合继承(原型链继承...

  • 构造函数原型的继承方式分析

    1.通过原型链继承 综上我们可以总结出 通过原型链来实现继承的原理通过原型链来实现继承的原理原型链继承方案中,父类...

  • Javascript 面向对象的程序设计(原型链与继承)

    继承 原型链 讲原型的时候提到过继承,设计原型的初衷就是为了继承,原型链是实现继承的主要方法。那什么是原型链,还记...

  • JavaScript继承方式详解

    JavaScript实现继承的方式主要有两种: 原型链继承和借助构造函数继承 一、原型链继承 原型链继承的主要思想...

  • js_继承及原型链等(四)

    js_继承及原型链等(三) 1. 继承 依赖于原型链来完成的继承 发生在对象与对象之间 原型链,如下: ==原型链...

  • js实现继承的几种方式

    js实现继承有几种方式,这里我们主要探讨 原型链继承 构造继承 组合继承(原型链和构造继承组合到一块,使用原型链实...

网友评论

    本文标题:this 原型链 继承

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