JS----this && JS繼承

參考學習:https://www.cnblogs.com/lisha-better/p/5684844.html
1.普通函數調用(window)
2.做爲構造函數調用()
3.做爲方法調用
4.使用call/apply/bind調用
5.ES6箭頭函數調用(this取決於包裹箭頭函數的第一個普通函數)html

**setTimeout()由window對象調用
call()參數爲空,this指向window
匿名函數,this也指向window
在這裏插入圖片描述web

在事件中,this指向觸發這個事件的對象,特殊的是,IE中的attachEvent中的this老是指向全局對象Windowapp

參考學習:https://www.cnblogs.com/chenwenhao/p/6980401.html
https://www.imooc.com/article/20162
https://www.cnblogs.com/humin/p/4556820.htmlsvg

在這裏插入圖片描述關於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

存在問題:this

1.包含引用類型值的原型屬性會被全部實例共享(修改),而在構造函數中的基本類型和引用類型屬性均不可改變(const附體)
2.建立子類型的實例時,不能向超類的構造函數中傳遞傳遞參數
3.沒法實現多繼承prototype

2.構造函數繼承(在子類型構造函數的內部調用超類型)code

子類型構造函數中向超類型構造函數傳參

問題:函數沒法複用xml

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
相關文章
相關標籤/搜索