JavaScript中的constructor和繼承


概述

這是我在看JavaScript面向對象編程指南的時候,對constructor和繼承的總結。

關於它們的詳細知識,可以上網查到,所以我只寫那些網上沒有的。

內容

  • constructor的理解
  • constructor的實際用途
  • constructor的陷阱
  • 從應用角度理解繼承
  • 函數構造器的繼承
  • 純對象的繼承

constructor的理解

constructor 屬性是一個指針,指向創建此對象的函數。(可以更改)

constructor的實際用途

看下面這段代碼:

var a,b;
(function(){
  function A (arg1,arg2) {
    this.a = 1;
    this.b=2; 
  }

  A.prototype.log = function () {
    console.log(this.a);
  }
  c = new A();
})()
c.log();
// 1

實例c是用閉包建立的,但是因為A是在閉包里面,所以我們不能直接訪問A。但是如果需要給A添加方法怎么辦呢?方法是用constructor

c.constructor.prototype.log2 = function () {
  console.log(2)
}

c.log2();
// 2

constructor的陷阱

//繼承
Child.prototype = new F();
Child.prototype.constructor = Child;

我們一般在繼承中,要給constructor屬性進行重置,比如上面那段代碼,這是為什么呢?

先來看看一個例子:

function Dog(){this.tail = true;}
var benji = new Dog();
Dog.prototype.say = function(){return 'woof';};

Dog.prototype = {paws:4}
var lucy = new Dog();

benji.constructor.prototype.paws
//4
lucy.constructor.prototype.paws
//undefined

其中,benjilucy都是Dog()的子對象,但是結果卻不相同。造成這種結果的原因是Dog.prototype = {paws:4}重置了Dog()的原型。(原理不明,貌似和__proto__有關。)

如果在Dog.prototype = {paws:4}后面再加一條語句Dog.prototype.constructor = Dog;結果就一樣了。這也是為什么在繼承中要重置constructor的原因。

從應用角度理解繼承

繼承,就是對父元素的代碼復用。

//父元素是函數構造器
function Parent() {
	this.id = 3;   //帶this的自身屬性
	var od = 5;  //不帶this的自身屬性
}
Parent.prototype.ud = 7;  //原型屬性

//父元素是純對象
Parent= {id:9};
Parent.prototype.ud = 7;

綜合考慮一下,父元素分為2種:函數構造器和純對象。父元素里面的代碼又分為自身屬性和原型屬性。(方法和屬性差不多,所以只考慮屬性。)

所以我們分別來討論函數構造器和純對象的代碼復用,即屬性繼承。

函數構造器的繼承

  • 只繼承原型屬性

很簡單,只需要把父對象的原型賦值給子對象即可。(原型繼承法

Child.prototype = Parent.prototype;

但是這樣的話,修改子對象的原型會影響父對象的原型,所以我們考慮用閉包。(臨時構造器法

var F = function() {};
F.prototype = Parent.prototype;
Child.prototype = new F();
Child.prototype.constructor = Child;

但是如果子對象的prototype本來就有值,所以不能直接進行prototype的賦值。這個時候我們可以直接把屬性拷貝過去。(原型屬性拷貝法

var p = Parent.prototype;
var c = Child.prototype;
for (i in p) {
    c[i] = p[i];
}

當然,還有深拷貝法,這里就不貼代碼了。

  • 只繼承自身屬性。

首先想到的就是拷貝法,上面貼過代碼這里就補貼了。但是拷貝法只能繼承父對象中不帶this的自身屬性。

如果想只繼承帶this的自身屬性,可以用構造器借用法

function Child() {
    Parent.apply(this, argument);
}

如果想全部繼承的話,那就只能兩者結合了。

  • 同時繼承自身屬性和原型屬性

這個時候,我們第一個想到的就是用new。(原型鏈法

Child.prototype = new Parent();

需要注意的是,這時子對象僅繼承父對象中帶有this的自身元素,不繼承不帶this的自身元素。

其它方法就只能結合上面多個方法了。

純對象的繼承

  • 只繼承原型屬性。

和函數構造器的繼承一樣。

  • 只繼承自身屬性。

當父元素是純對象的時候,它里面沒有this的自身元素。所以只需用拷貝法即可。

另外,還可以把父元素的自身元素放到子元素的prototype里面去。(原型繼承法)

function object() {
    function F(){};
    F.prototype = Parent;
    return new F();
}
  • 同時繼承自身屬性和原型屬性

這個就是結合上述方法了。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM