原型與繼承

原型

原型鏈

var Foo = function(name){
    this.name = name
}
var foo = new Foo('luoyi')
複製代碼

Zepto中是如何使用原型鏈

寫一個實際應用中原型鏈繼承的例子:封裝一個DOM查詢的例子

function Elem(id){
  this.elem = document.getElementById(id)
}
Elem.prototype.html = function(val){
  var elem = this.elem
  if(val){
    elem.innerHTML = val
  }else{
    return elem.innerHTML
  }
}
Elem.prototype.on = function(type,fn){
  var elem = this.elem
  elem.addEventListener(type,fn)
}
var div1 = new Elem('div1')
複製代碼

繼承

建立對象的幾種方法

對象字面量

var obj1 = {
    name:'luoyi'
}
var obj2 = new Object({
    name:'louyi3'
}) //也能夠歸類爲構造函數形式
複製代碼

構造函數形式

var Foo = function(){
    this.name = 'luoyi'
}
var foo = new Foo()
複製代碼

Object.create()方法

var obj = {
    name:'luoyi'
}
var obj2 = Object.create(obj)
複製代碼

繼承

類的聲明

// ES5的實現方式
funciton Animal1(){
    this.name = 'name'
}
複製代碼
// ES6中的實現方式
class Animal2{
    constructor(){
      this.name = 'name'
    }
}
typeof Animal2 // 'function' 類的數據類型就是函數,類自己就指向構造函數
Animal2 === Animal2.prototype.constructor // true
複製代碼

實例化類的對象

ES5的實例化方式與ES6的實例化方式相同html

var cat = new Animal()
複製代碼

類的繼承

繼承的本質是原型鏈bash

藉助構造函數實現繼承

function Parent (){
  this.name = 'parent'
}
function Child (){
  Parent.call(this) 
  this.type = 'child'
}
Parent.prototype.say = function(){
  console.log('say hi')
}
var child = new Child()
child.say() //沒有這個方法
複製代碼

  • 缺點:Parent原型鏈上的方法是沒有辦法被繼承的,沒有實現真正的繼承。

藉助原型鏈實現繼承

function Parent2 (){
    this.name = 'parent2'
}
function Child2(){
    this.type = 'child2'
}
Child2.prototype = new Parent2()
var child2 = new Child2()
複製代碼

  • 缺點:
  1. Child2的全部實例對象共享__proto__:c2.__proto__ === c22.__proto__
function Parent2 (){
    this.name = 'parent2';
    this.play = [1,2,3]
}
function Child2(){
    this.type = 'child2'
}
Child2.prototype = new Parent2()
var c2 = new Child2()
var c22 = new Child2()
c2.play.push(4)
c22.play // [1,2,3,4]
複製代碼
  1. child2.constructor指向的Parent2

組合繼承:構造函數繼承和原型鏈繼承的組合

function Parent3(){
    this.name = 'parent3'
    this.play = [1,2,3]
}
function Child3(){
    Parent3.call(this)
    this.type = 'child3'
}
Child3.prototype = new Parent3();
var s = new Child3()
var s1 = new Child3()
s.play.push(4)
s.play() //[1,2,3,4]
s1.play() // [1,2,3]
複製代碼
  • 缺點:父類的構造函數執行了兩次

組合繼承的優化方式1

function Parent3(){
    this.name = 'parent3'
    this.play = [1,2,3]
}
function Child3(){
    Parent3.call(this)
    this.type = 'child3'
}
//Child3.prototype = new Parent3();
Child3.prototype = Parent3.prototype;
var s = new Child3()
var s1 = new Child3()
s.play.push(4)
s.play() //[1,2,3,4]
s1.play() // [1,2,3]
複製代碼
  • 缺點:constructor指向的是父類的構造函數

組合集成的優化方式2

function Parent3(){
    this.name = 'parent3'
    this.play = [1,2,3]
}
function Child3(){
    Parent3.call(this)
    this.type = 'child3'
}
//Child3.prototype = new Parent3();
//Child3.prototype = Parent3.prototype;
Child3.prototype = Object.create(Parent3.prototype) 
Child3.prototype.constructor = Child3
複製代碼
相關文章
相關標籤/搜索