javascript繼承(一)—類的屬性研究

    本篇文章主要針對javascript的屬性進行分析,因爲javascript是一種基於對象的語言,自己沒有類的概念,因此對於javascript的類的定義有不少名字,例於原型對象,構造函數等,它們都是指javascript中的類。例如:function Person(){} var p = new Person(); 這裏的Person能夠看做一個類,而p則是這個類的實例也能夠稱爲對象。javascript

    這裏主要分析js裏面的四種屬性。java

    私有屬性,指定義在類中用var聲明的,即var propertyName = sonmeValue,只能在這個類裏面進行訪問,不能被繼承,也不能在原型方法中訪問的屬性。
    特權屬性(實例屬性),指在類中或者說在構造函數中(js裏是同一個東西),使用this關鍵字,即this.propertyName = someValue,該屬性在類中能夠訪問,在原型方法中能夠訪問,在該類的對象中也 能被訪問,甚至用call或apply繼承時也能訪問。
  共有屬性,指經過ClassName.prototype.propertyName=someValue 來定義的,若是該屬性在類中沒定義,即沒有重命的特權屬性,則能夠當特權屬性被訪問,即能在對象中調用,經過prototype繼承的子類也能訪問。
    靜態屬性,直接ClassName.propertyName=someValue 來定義,至關於一個命名空間,在類的內部外部都能訪問。
app

例1: 各類屬性定義函數

function Person(){
     var private_name = "小明"; //私有屬性
     var private_age = 10; //私有屬性
     this.privilege_name = "小紅"; //特權屬性
     this.privilege_age = 9; //特權屬性
  }
    Person.prototype.public_name = "小芳"; //公有屬性
    Person.prototype.public_age =8; //共有屬性
    Person.static_name = "小李"; //靜態屬性
    Person.static_age = 7; //靜態屬性
 
    var pp = new Person();
    pp.name = '小王'; //靜態屬性
    pp.age = 6; //靜態屬性

在這個例子裏指出了這四種屬性的定義方式。注意靜態屬性裏,由於Person和pp都是Object實例,以下面代碼執行結果能夠看出。this

console.log(Person instanceof Object,pp instanceof Object); //true truespa

因此均可以定義靜態屬性。prototype

下面來分析一下這些屬性的訪問權限。code

例2:各類屬性的訪問權限 對象

function Person(){
    var private_name = '小明';
    var private_age = 10;    
 this.privilege_name = '小紅'; 
 this.privilege_age = 9; 
 
    //定義一個特權方法
 this.showPrivilegeName = function(){
    console.log(private_name);             // private_name is not defined .說明私有屬性能夠在特權方法中訪問.
    console.log(this.privilege_name );         //輸出:"小紅"。說明特權屬性能夠在特權方法中訪問
    console.log(this.public_name);            //輸出:"小芳"。說明共有屬性能夠在特權方法中訪問
    console.log(Person.static_name);        //輸出:"小李"。說明類的靜態屬性能夠在特權方法中訪問
  }
}
 
Person.prototype.public_name = '小芳';
Person.prototype.public_age =8;   
Person.static_name = '小李';   
Person.static_age = 7;    
var pp = new Person();
pp.name = '小王';       
pp.age = 6;
 
//定義一個原型方法
Person.prototype.showName = function(){
  //console.log(private_name);         // private_name is not defined .說明私有屬性不能在原型方法中訪問.
  console.log(this.privilege_name );         //輸出:"小紅"。說明特權屬性能夠在原型方法中訪問
  console.log(this.public_name);        //輸出:"小芳"。說明共有屬性能夠在原型方法中訪問
  console.log(Person.static_name);        //輸出:"小李"。說明類的靜態屬性能夠在原型方法中訪問
}   
 
pp.showPrivilegeName();
pp.showName();
console.log(pp.private_name);            //undefined 私有屬性不能在實例化的對象中訪問 
console.log(pp.privilege_name );         //輸出:"小紅"。說明特權屬性能夠在原型方法中訪問
console.log(pp.public_name);            //輸出:"小芳"。說明共有屬性能夠在原型方法中訪問
console.log(Person.static_name);        //輸出:"小李"。說明類的靜態屬性能夠在原型方法中訪問
console.log(pp.name);                 //輸出:"小王"。說明實例對象的靜態屬性能夠在原型方法中訪問

能夠看到若是特權屬性和公共屬性重名的話,訪問特權屬性,若是特權屬性不存在的話則訪問共有屬性。 另外若是用delete對象的屬性刪掉是刪的特權屬性,刪除後能夠繼續訪問共有屬性。 對於對象的靜態屬性只能該對象能訪問,類的其它對象是不能訪問的。blog

例3:特權屬性和對象靜態屬性之間的優先級問題

function Person(){
  this.name = '小李';
}
var p1 = new Person();
p1.name = '小紅';
p1.age = 10
console.log(p1.name); //小紅
console.log(p1.age); //10
delete p1.name
console.log(p1.name); //undefined

例4特權屬性和對象靜態屬性之間的優先級問題

function Person(){ 
this.name = '小李'; 
} 
var p1 = new Person(); 
p1.name = '小紅'; 
p1.age = 10 
console.log(p1.name); //小紅 console.log(p1.age); //10 delete p1.name console.log(p1.name); //undefined

能夠看到若是建立了對象後,給該對象建立一個與特權屬性同名的靜態屬性,特權屬性的值會被覆蓋,若是用delete刪除後,再訪問爲undefined。

總結:對象的靜態屬性只能該對象自己能訪問,優先級:對象的靜態屬性>類的特權屬性>共有屬性。其中對象的靜態屬性會覆蓋類的特權屬性,而類的特權屬性並不會覆蓋共有屬性,即用delete刪除該對象的屬性是刪除它的特權屬性,並不能刪除類的共有屬性。 對於類靜態屬性和方法,是處處都能訪問的,即至關於命名空間。對於類的共有屬性,特權屬性在外部是能夠訪問的。對於私有屬性和方法,只有類的內部能使用。其中類的共有屬性和方法能夠訪問類的特權屬性和方法,但不能訪問類的私有屬性和方法。
相關文章
相關標籤/搜索