前端面试题(第二弹)——js继承(call、apply、bind详解)

前端面试题(第二弹)——js继承(call、apply、bind详解)

  • 一、三种修改this指向的方法
    • 1.call()
    • 2.apply()
    • 3.bind()
  • 二、 js实现继承的方法
    • 1.call() +构造函数实现继承
    • 2.ES6 Class实现继承
    • 3. 原型链继承
    • 4.组合继承

一、三种修改this指向的方法

1.call()

call()是一个方法,是函数的方法,以函数来调用。

function fun () {
	console.log(this.name)
}
let dog = {
    name:"汪汪",
    eat (food1,food2){
     console.log("我喜欢吃"+food1+food2)
    }
}
let cat = {
	name:"喵喵"
}
fun.call(cat)  //喵喵
dog.eat.call(cat,"鱼肉","鸡蛋") //我喜欢吃鱼肉鸡蛋

call() 可以调用函数,可以改变函数中的this指向。
call()方法中的第一个参数是用来改变Fun的this指向,后面的参数可以是多个,代表传递的参数。

2.apply()

apply()和call() 的用法一样,区别在于传入的参数不一样,apply()传参时传入的是数组。

dog.eat.apply(cat,["鱼肉","鸡蛋"]) //我喜欢吃鱼肉鸡蛋

3.bind()

bind()和call() 的用法一样,区别在于bind()不会执行函数。会返回一个函数,好处在于我们可以多次调用。


let Fun = dog.eat.apply(cat,["鱼肉","鸡蛋"]) 
Fun();
//我喜欢吃鱼肉鸡蛋
Fun();
//我喜欢吃鱼肉鸡蛋

二、 js实现继承的方法

1.call() +构造函数实现继承

子类可以使用父类的方法

//构造函数大写开头以区分,不需要return
function Animal() {
	this.eat = function(){
		console.log("吃东西")
	}
}
function Bird() {
	this.fly = function() {
 	console.log("我会飞")
}
}

function Cat() {
//使用cat的this调用Animal/Bird Animal/Bird中的this也变成cat 所以可以调用
	Animal.call(this);
	Bird.call(this)
	this.sayName = function(){
    console.log("输出自己的名字")
 }
}
let cat = new Cat();
cat.eat()
cat.fly()
cat.sayName()

2.ES6 Class实现继承

class Person {
  constructor(name, age) {
    this.name = name
    this.age = age
  }
  running() {
    console.log("running~")
  }
  eating() {
    console.log("eating~")
  }
}
// 使用 extends 继承 Person类
class Student extends Person {
  constructor(name, age, sno, score) {
    // 调用父类构造函数
    super(name, age);
    this.sno = sno;
    this.score = score;
  }
  // 定义自己的实例方法
  studying() {
    console.log('studying~');
  }
}
 
const stu1 = new Student('why', 18, 111, 100);
// 调用父类的实例方法
stu1.running();
stu1.eating();
// 调用自己的实例方法
stu1.studying();

3. 原型链继承

function Parent() {
   this.isShow = true
   this.info = {
       name: "mjy",
       age: 18,
   };
}
 
Parent.prototype.getInfo = function() {
   console.log(this.info);
   console.log(this.isShow);
}
 
function Child() {};
Child.prototype = new Parent();
 
let Child1 = new Child();
Child1.info.gender = "男";
Child1.getInfo(); // {name: 'mjy', age: 18, gender: '男'} ture
 
let child2 = new Child();
child2.isShow = false
console.log(child2.info.gender) // 男
child2.getInfo(); // {name: 'mjy', age: 18, gender: '男'} false

4.组合继承

将 原型链 和 借用构造函数 的组合到一块。使用原型链实现对原型属性和方法的继承,而通过借用构造函数来实现对实例属性的继承。这样,既通过在原型上定义方法实现了函数复用,又能够保证每个实例都有自己的属性

function Person(gender) {
  console.log('执行次数');
  this.info = {
    name: "mjy",
    age: 19,
    gender: gender
  }
}
 
Person.prototype.getInfo = function () {   // 使用原型链继承原型上的属性和方法
  console.log(this.info.name, this.info.age)
}
 
function Child(gender) {
  Person.call(this, gender) // 使用构造函数法传递参数
}
 
Child.prototype = new Person()
 
let child1 = new Child('男');
child1.info.nickname = 'xiaoma'
child1.getInfo()
console.log(child1.info);
 
let child2 = new Child('女');
console.log(child2.info);

你可能感兴趣的:(前端,javascript,开发语言)