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


    本篇文章主要針對javascript的屬性進行分析,由於javascript是一種基於對象的語言,本身沒有類的概念,所以對於javascript的類的定義有很多名字,例於原型對象,構造函數等,它們都是指javascript中的類。例如:function Person(){} var p = new Person(); 這里的Person可以看作一個類,而p則是這個類的實例也可以稱為對象。

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

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

例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實例,如下面代碼執行結果可以看出。

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

所以都可以定義靜態屬性。

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

例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對象的屬性刪掉是刪的特權屬性,刪除后可以繼續訪問共有屬性。 對於對象的靜態屬性只能該對象能訪問,類的其它對象是不能訪問的。

例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刪除該對象的屬性是刪除它的特權屬性,並不能刪除類的共有屬性。 
對於類靜態屬性和方法,是到處都能訪問的,即相當於命名空間。
對於類的共有屬性,特權屬性在外部是可以訪問的。
對於私有屬性和方法,只有類的內部能使用。其中類的共有屬性和方法可以訪問類的特權屬性和方法,但不能訪問類的私有屬性和方法。


免責聲明!

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



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