JS----this && JS继承

参考学习:https://www.cnblogs.com/lisha-better/p/5684844.html
1.普通函数调用(window)
2.作为构造函数调用()
3.作为方法调用
4.使用call/apply/bind调用
5.ES6箭头函数调用(this取决于包裹箭头函数的第一个普通函数)

**setTimeout()由window对象调用
call()参数为空,this指向window
匿名函数,this也指向window
在这里插入图片描述

在事件中,this指向触发这个事件的对象,特殊的是,IE中的attachEvent中的this总是指向全局对象Window

参考学习:https://www.cnblogs.com/chenwenhao/p/6980401.html
https://www.imooc.com/article/20162
https://www.cnblogs.com/humin/p/4556820.html

在这里插入图片描述关于Function和Object创建实例之间的关系
在这里插入图片描述基于原型链继承的链图,对继承有个具体化的概念: (这个是核心继承部分)
上图整体的继承链

js继承:
1.原型链继承
特点;

   1.要想为子类新增属性和方法,必须要在new Animal()这样的语句之后执行,不能放到构造器中
    2.无法实现多继承
    3.来自原型对象的所有属性被所有实例共享
    4.创建子类实例时,无法向父类构造函数传参


  function SuperType () {
    this.property = true;
}

SuperType.prototype.getSuperValue = function() {
    return this.property;
};

function SubType() {
    this.subproperty = false;
}

//继承SuperType
**SubType.prototype = new SuperType();**

SubType.prototype.getSubValue = function() {
    return this.subproperty;
}

var instance =new SubType();
console.log(instance.getSuperValue());  // true

存在问题:

1.包含引用类型值的原型属性会被所有实例共享(修改),而在构造函数中的基本类型和引用类型属性均不可改变(const附体)
2.创建子类型的实例时,不能向超类的构造函数中传递传递参数
3.无法实现多继承

2.构造函数继承(在子类型构造函数的内部调用超类型)

子类型构造函数中向超类型构造函数传参

问题:函数无法复用

 function SuperType() {
     this.colors = ["red","blue","green"];    
}

function SubType() {
   //继承了SuperType   --重新创建SuperType构造函数属性的副本
   SuperType.call(this);
}

var instance1 = newe SubType();
instance1.colors.push("black");
console.log(instance1.colors);  //"red,blue,green,black"

var instances2 = new SubType();
console.log(instance2.colors);  //"red,blue,green" --完美实现了继承构造函数属性

3.组合继承(避免了原型链和构造函数继承的缺陷)

弥补了方式2的缺陷,可以继承实例属性/方法,也可以继承原型属性/方法
既是子类的实例,也是父类的实例
不存在引用属性共享问题
可传参
函数可复用

缺点:

调用了两次父类构造函数,生成了两份实例(子类实例将子类原型上的那份屏蔽了)

function SuperType(name) {
    this.name = name;
    this.colors = ["red","blue","green"];
}

SuperType.prototype.sayName = function() {
    console.log(this.name);
};

function SubType(name,age){
    //继承属性  --重新创建SuperType构造函数属性的副本
    SuperType.call(this,name);

    this.age = age;
}

//继承方法
SubType.prototype = new SuperType();
SubType.prototype.constructor = SubType;
SubType.prototype.sayAge = function() {
    console.log(this.age);
};

var instance1 =new SubType("Nicholas",29);
instance1.colors.push("black");
console.log(instance1.colors);   // "red,blue,green,black"
instance1.sayName();       // "Nicholas"
instance1.sayAge();       // 29

var instance2 = new SubType("Greg",22);
console.log(instance2.colors);  // "red,blue,green"
instance2.sayName();    // "Greg"
instance2.sayAge();    // 22

4.实例继承
特点:

不限制调用方式,不管是new 子类()还是子类(),返回的对象具有相同的效果

缺点:

实例是父类的实例,不是子类的实例
不支持多继承

// 定义一个动物类
function Animal (name) {
  // 属性
  this.name = name || 'Animal';
  // 实例方法
  this.sleep = function(){
    console.log(this.name + '正在睡觉!');
  }
}
// 原型方法
Animal.prototype.eat = function(food) {
  console.log(this.name + '正在吃:' + food);
};
function Cat(name){
  var instance = new Animal();
  instance.name = name || 'Tom';
  return instance;
}

// Test Code
var cat = new Cat();
console.log(cat.name);
console.log(cat.sleep());
console.log(cat instanceof Animal); // true
console.log(cat instanceof Cat); // false

5.拷贝继承
特点:

支持多继承

缺点:

效率较低,内存占用高(因为要拷贝父类的属性)
无法获取父类不可枚举的方法(不可枚举方法,不能使用for in 访问到)

function Cat(name){
  var animal = new Animal();
  for(var p in animal){
    Cat.prototype[p] = animal[p];
  }
  Cat.prototype.name = name || 'Tom';
}

// Test Code
var cat = new Cat();
console.log(cat.name);
console.log(cat.sleep());
console.log(cat instanceof Animal); // false
console.log(cat instanceof Cat); // true

6.寄生组合继承

function Cat(name){
  Animal.call(this);
  this.name = name || 'Tom';
}
(function(){
  // 创建一个没有实例方法的类
  var Super = function(){};
  Super.prototype = Animal.prototype;
  //将实例作为子类的原型
  Cat.prototype = new Super();
})();

// Test Code
var cat = new Cat();
console.log(cat.name);
console.log(cat.sleep());
console.log(cat instanceof Animal); // true
console.log(cat instanceof Cat); //true
posted @ 2019-04-20 19:11  princeness  阅读(204)  评论(0编辑  收藏  举报