JS對象的概念、聲明方式等及js中的繼承與封裝

来源:https://www.cnblogs.com/chenyingying0/archive/2020/02/14/12305709.html

對象的遍歷 對象可以當做數組處理,使用for in var person={}; person.name="cyy"; person.age=25; person.infos=function(){ alert(this.name+" "+this.age); } for(var i in pers ...


對象的遍歷

對象可以當做數組處理,使用for in

var person={};
person.name="cyy";
person.age=25;
person.infos=function(){
    alert(this.name+" "+this.age);
}

for(var i in person){
    console.log(i);//屬性名或方法名
    console.log(person[i]);//屬性值或方法值
}

 

 使用構造函數聲明的對象,需要實例化之後再進行遍歷

function Person(){
    this.name="cyy";
    this.age=25;
}
var p=new Person();
for(var i in p){
    console.log(i+":"+p[i]);
}

對象在記憶體中的分佈

參考以下神圖

 

 

 封裝:把對象的內部數據和操作細節進行隱藏

提供private關鍵詞隱藏某些屬性和方法,限制被封裝的數據或者內容的訪問,只對外提供一個對象的專門訪問的介面

介面一般為調用方法

不過js沒有提供這樣的關鍵詞,但可以通過閉包來實現

函數內部聲明的變數,外部是訪問不到的

function fn(){
    var n=1;
    function fn2(){//特權方法
        alert(++n);
    }
    return fn2;
}
fn()();//2
//封裝
function Person(){
    var name="cyy";
    function _name(){
        alert(name);
    }
    this.name=function(){//這是給外部的介面
        return _name;
    }
}
var p=new Person();
var fn=p.name();
fn();//cyy

封裝的缺點:1、占用記憶體   2、不利於繼承


 

利用閉包特性來封裝一個對象student,運用對象student存儲一個學生的信息,信息包括姓名,性別和年齡,這些信息不可被外部直接訪問,只能通過對象的方法獲取 

student的數據結構如下:

 

 

//封裝
function Student(){
    var obj={};
    function _set(name,sex,age){
        obj.name=name;
        obj.sex=sex;
        obj.age=age;
    }
    function _get(){
        return obj.name+" "+obj.sex+" "+obj.age;
    }
    obj.get=function(){//對外介面
        return _get;
    }
    obj.set=function(){//對外介面
        return _set;
    }
    return obj;
}
var stu=new Student;
stu.set()("小明", "男", 23);
console.log(stu.get()());//小明 男 23

原型和原型鏈

原型:利用 prototype 添加屬性和方法,prototype對象

原型鏈:JS在創建對象時,有一個 __proto__ 的內置屬性,指向它的原型對象 prototype

var Person=function(){}
var p=new Person();
Person.prototype.say=function(){
    alert("老娘超美");
}
p.say();
/*
p沒有say方法,所以會去p.__proto__里找
p.__proto__是一個對象,指向Person.prototype
Person.prototype中有say方法
 */


/*
創建對象的過程
1、創建對象 var p={}
2、將Person的原型對象賦值給p  p.__proto__=Person.prototype
3、初始化對象p  Person.call(p)
 */
alert(p.__proto__==Person.prototype);//true

原型和原型鏈,實現原型繼承

var Person=function(){}//Person是一個對象
Person.prototype.say=function(){
    alert("陳鶯鶯超美");
}
var Cyy=function(){};//Cyy也是一個對象
Cyy.prototype=new Person();//將Cyy的原型指向Person,實現Cyy繼承自Person
Cyy.prototype.sing=function(){
    alert("陳鶯鶯會唱歌");
}

var me=new Cyy();
me.say();//陳鶯鶯超美
me.sing();// 陳鶯鶯會唱歌

/*
分析:me.__proto__  ->  Cyy.ptototype  -> Person.prototype
Person是父  Cyy是子
繼承:如果子類中沒有的,會繼承自父類;如果子類和父類中都有,那麼子類的會覆蓋掉父類的
 */

__proto__ 實現原型繼承

function Person(name,age){
    this.name=name;
    this.age=age;
}
Person.prototype.say=function(){
    alert(this.name+" "+this.age);
}

function Student(){};
Student.prototype=new Person("cyy",25);
//Person是Student的父類
//子類必須繼承自父類的實例
Student.prototype.grade=3;
Student.prototype.test=function(){
    alert(this.grade);
}

var s=new Student();
s.say();//cyy 25
s.test();//3
//s.__proto__ -> Student.prototype -> Person.prototype

原型的值可以是一個對象,也可以是null

原型鏈的最終指向null

alert(Object.prototype.__proto__);//null
// 情況一
function Parent(){
    this.name="parent";
    this.age=45;
}
function Child(){
    this.age=25;
}
Child.prototype.name="child";
Child.prototype=new Parent();
var c=new Child();
console.log(c.name);//parent

// 情況二
function Parent(){
    this.name="parent";
    this.age=45;
}
function Child(){
    this.age=25;
}
Child.prototype=new Parent();
Child.prototype.name="child";
var c=new Child();
console.log(c.name);//child

情況一中,Child.prototype=new Parent(); 這一句覆蓋掉了前面的 Child.prototype.name="child";

屬性的值與代碼執行順序有關,後繼承的父級的,會覆蓋住先定義的自己的


 

創建一個動物類的對象 ,對象中有動物名稱和數量的屬性 。創建一個貓的對象並繼承動物類對象 ,併為貓對象定義一個方法 。實例化一個貓對象 ,調用其方法 ,彈出動物名稱和數量

function Animal(name,number){
    this.name=name;
    this.number=number;
}
function Cat(){};
Cat.prototype=new Animal("cat",30);
Cat.prototype.info=function(){
    alert(this.name+" "+this.number);
}
var c=new Cat();
c.info();//cat 30

構造函數的繼承

在子類內部構造父類的對象來實現繼承

父對象被子對象繼承後,所有的屬性和方法,都會傳遞到子對象中

function Parent(name){
    this.name=name;
    this.pSay=function(){
        alert(this.name);
    }
}
function Child(name,age){
    this.obj=Parent;
    this.obj(name);//繼承了父元素中的兩句代碼
    this.age=age;
    this.cSay=function(){
        alert(this.name+" "+this.age);
    }
}
var p=new Parent("爸爸");
p.pSay();//爸爸
var c=new Child("女兒",25);
c.cSay();//女兒 25
c.pSay();//女兒

對象內置方法中的apply和call都可用於繼承,兩者的區別在於傳參方式不同

obj.call( 方法, var1, var2...)

obj.apply( 方法, [var1, var2...])

function Parent(name,age,sex){
    this.name=name;
    this.age=age;
    this.sex=sex;
    this.say=function(){
        alert(this.name+" "+this.age+" "+this.sex);
    }
}
function Child(name,age){
    //實現繼承
    Parent.call(this,name,age);//this是指Child
}
function Child2(name,age){
    //實現繼承
    Parent.apply(this,[name,age]);//this是指Child
}

var c=new Child("cyy",25);
c.say();
//cyy 25 undefined
//Child也擁有了Parent的屬性和方法
var c2=new Child2("cyy2",25);
c2.say();//cyy2 25 undefined

使用構造方法創建一個動物類對象Animal, 對象中定義屬性有動物名稱和數量 ,並且定義一個方法。再創建兩個動物的對象(如貓和狗),一個動物使用call方法實現繼承Animal, 一個動物使用apply方法實現繼承Animal。分別實例化兩個動物並彈出動物的名稱和數量

function Animal(name,num){
    this.name=name;
    this.num=num;
    this.getInfo=function(){
        alert(this.name+" "+this.num);
    }
}
function Cat(name,num){
    Animal.call(this,name,num);
}
function Dog(name,num){
    Animal.apply(this,[name,num]);
}
var c=new Cat("cat",20);
c.getInfo();//cat 20
var d=new Dog("dog",30);
d.getInfo();//dog 30

JS面向對象的關鍵詞

instanceof  變數是否是對象的實例

var arr=new Array();
console.log(arr instanceof Array);//true
console.log(arr instanceof Object);//true

function Person(){};
var p=new Person();
console.log(p instanceof Person);//true
console.log(p instanceof Object);//true

 

delete 刪除對象屬性(不能刪除原型鏈中的屬性和方法

function Person(){
    this.name="cyy";
    this.eat=function(){
        alert("吃飯");
    }
}
var p=new Person();
console.log(p.name);//cyy
delete p.name;//刪除對象的屬性
console.log(p.name);//undefined

p.eat();//吃飯
delete p.eat();//吃飯  刪除對象的方法,失敗
p.eat();//吃飯

var name="cyy";
console.log(name);//cyy
delete name;
console.log(name);//name is not defined

 

call 參數逐個實現繼承

apply 參數以數組方式實現繼承

function add(a,b){
    alert(a+b);
}
function sub(a,b){
    alert(a-b);
}
add.call(sub,4,8);
//12 調用的是add這個方法
add.call(sub2,4,8);
//sub2 is not defined 只能引用一個已經存在的對象

add.apply(sub,[3,2]);
function Animal(){
    this.name="animal";
    this.show=function(){
        alert(this.name);
    }
}
function Cat(){
    this.name="cat";
}
var a=new Animal();
var c=new Cat();
a.show.call(c);//cat c擁有了a所擁有的show方法
a.show.apply(c,[]);//cat c擁有了a所擁有的show方法

創建兩個數組 ,並運用apply實現兩個數組的拼接

var arr1=[2,3];
var arr2=[4,5];
arr1.push.apply(arr1,arr2);
//調用的是apply前面的方法:arr1.push
console.log(arr1);

 

arguments 實參的類數組對象

callee  返回正在執行的function對象,返回的是function的內容

arguments.callee

function fn(){
    console.log(arguments.callee);
    /*ƒ fn(){
        console.log(arguments.callee);
        }
    */
    //console.log(arguments.callee());不停調用自身,陷入死迴圈
}
fn();

 

常用於遞歸函數調用函數自身

var sum=function(n){
    if(n<=1) return 1;
    return n+sum(n-1);
}
console.log(sum(4));//10
var sum=function(n){
    if(n<=1) return 1;
    return n+arguments.callee(n-1);
}
console.log(sum(4));//10

 

this 指向當前對象

1、this函數調用

var x=1;
function fn(){
    this.x=2;//this改變的是全局變數的x的值
}
fn();
console.log(x);//2

2、this作為方法調用

構造函數內指代當前對象

function Person(){
    this.name="cyy";
    this.show=function(){
        alert(this.name);
    }
}
var p=new Person();
p.show();//cyy

3、在call和apply中,this作為第一個參數

var name="cyy";
function show(){
    alert(this.name);
}
var obj={};
obj.name="cyy2";
obj.showName=show;
obj.showName.apply();//調用show(),this指向全局
obj.showName.apply(window);//同上
obj.showName.apply(obj);//調用show(),this指向obj

用arguments計算參數總和

function sum(){
    var sum=0;
    for(var i=0;i<arguments.length;i++){
        sum+=arguments[i];
    }
    return sum;
}
console.log(sum(2,5,7));//14

對象冒充:將父類的屬性和方法傳給子類,作為特權屬性和特權方法

function Parent(name,age){
    this.name=name;//特權屬性
    this.age=age;
    this.show=function(){//特權方法
        alert(this.name+" "+this.age);
    }
}
Parent.prototype.walk=function(){//非特權方法
    alert("walking...");
}

function Child(name,age,sex){
    this.obj=Parent;//對象冒充,可以使用父類的特權屬性和特權方法
    this.obj(name,age);
    this.sex=sex;
}
var c=new Child("cyy",25,"女");
c.show();//cyy 25
c.walk();// c.walk is not a function

 


您的分享是我們最大的動力!

更多相關文章
  • 1 SQL 的哲學 形如 Linux 哲學一切都是文件,在 SQL 領域也有這樣一條至理名言 2 關係資料庫 所謂關係資料庫(Relational database)是創建在關係模型基礎上的資料庫,藉助於集合代數等數學概念和方法來處理資料庫中的數據。 現實世界中的各種實體以及實體之間的各種聯繫均用關 ...
  • 該文為《 MySQL 實戰 45 講》的學習筆記,感謝查看,如有錯誤,歡迎指正 一、索引簡介 索引就類似書本的目錄,作用就是方便我們更加快速的查找到想要的數據。 索引的實現方式比較多,常見的有 ,`有序數組 搜索樹`。 1.1 哈希表 是將數據以 的形式存儲起來,簡單來說就是將 通過哈希函數換算成數 ...
  • 資料庫索引是資料庫系統中一個重要的概念,索引也叫做 key ,是一種用於提升資料庫查詢效率的數據結構,我們可以把索引理解成一本書的目錄,通過目錄我們可以快速找到對應章節的內容,同樣的,通過資料庫索引,我們可以快速找到數據表中對應的記錄。 ...
  • 上一章聊到 TsFile 的文件組成,以及數據塊的詳細介紹。詳情請見: 時序資料庫 Apache-IoTDB 源碼解析之文件數據塊(四) 打一波廣告,歡迎大家訪問IoTDB 倉庫,求一波 Star。 這一章主要想聊聊: TsFile索引塊的組成 索引塊的查詢過程 索引塊目前在做的改進項 索引塊 索引 ...
  • 簡單介紹了線性佈局和相對佈局,同時分析了xml文件三個固定開頭xmlns:namespace-prefix="namespaceURI" ...
  • 在無序列表ul>li中,無線列表的標誌是出現在各列表前面的圓點。在有序列表ol>li中,前面預設帶有數字,如何修改列表前面的項目符號,只需要通過list-style調整就好,常見的符號有(/*內容註釋部分*/)list-style-type:circle;/*空心圓*/list-style:none... ...
  • 常見的color, font-family, background 等css屬性都能夠設置鏈接的樣式,a鏈接的特殊性在於能夠根據它們所處的狀態來設置它們的樣式。a標簽與人交互的4個狀態屬於偽類狀態切換,常見的鏈接四種狀態為:a:link - 普通的、未被訪問的鏈接a:visited - 用戶已訪問的... ...
  • CSS文本屬性可定義文本的外觀,這是毫無疑問的,其次css可以通過以下屬性改變文字的排版,比方說letter-spacing實現字元間距text-indent: 2em;完成首行縮進2字元word-spacing改變了文字的間距,direction改變文本從左至右的閱讀順序,white-space處... ...
一周排行
  • 比如要拆分“呵呵呵90909086676喝喝999”,下麵當type=0返回的是中文字元串“呵呵呵,喝喝”,type=1返回的是數字字元串“90909086676,999”, private string GetStrings(string str,int type=0) { IList<strin ...
  • Swagger一個優秀的Api介面文檔生成工具。Swagger可以可以動態生成Api介面文檔,有效的降低前後端人員關於Api介面的溝通成本,促進項目高效開發。 1、使用NuGet安裝最新的包:Swashbuckle.AspNetCore。 2、編輯項目文件(NetCoreTemplate.Web.c ...
  • 2020 年 7 月 30 日, 由.NET基金會和微軟 將舉辦一個線上和為期一天的活動,包括 微軟 .NET 團隊的演講者以及社區的演講者。本次線上大會 專註.NET框架構建微服務,演講者分享構建和部署雲原生應用程式的最佳實踐、模式、提示和技巧。有關更多信息和隨時瞭解情況:https://focu... ...
  • #abp框架Excel導出——基於vue #1.技術棧 ##1.1 前端採用vue,官方提供 UI套件用的是iview ##1.2 後臺是abp——aspnetboilerplate 即abp v1,https://github.com/aspnetboilerplate/aspnetboilerp ...
  • 前言 本文的文字及圖片來源於網路,僅供學習、交流使用,不具有任何商業用途,版權歸原作者所有,如有問題請及時聯繫我們以作處理。 作者:碧茂大數據 PS:如有需要Python學習資料的小伙伴可以加下方的群去找免費管理員領取 input()輸入 Python提供了 input() 內置函數從標準輸入讀入一 ...
  • 從12年到20年,python以肉眼可見的趨勢超過了java,成為了當今It界人人皆知的編程語言。 python為什麼這麼火? 網路編程語言搜索指數 適合初學者 Python具有語法簡單、語句清晰的特點,這就讓初學者在學習階段可以把精力集中在編程對象和思維方法上。 大佬都在用 Google,YouT ...
  • 在社會上存在一種普遍的對培訓機構的學生一種歧視的現象,具體表現在,比如:當你去公司面試的時候,一旦你說了你是培訓機構出來的,那麼基本上你就涼了,那麼你瞞著不說,然後又通過了面試成功入職,但是以後一旦在公司被髮現有培訓經歷,可能會面臨被降薪,甚至被辭退,培訓機構出來的學生,在用人單位眼裡就是能力低下的 ...
  • from typing import List# 這道題看了大佬寫的代碼,經過自己的理解寫出來了。# 從最外圍的四周找有沒有為O的,如果有的話就進入深搜函數,然後深搜遍歷# 判斷上下左右的位置是否為Oclass Solution: def solve(self, board: List[List[s ...
  • import requests; import re; import os; # 1.請求網頁 header = { "user-agent":'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_5) AppleWebKit/537.36 (KHTML, li ...
  • import requests; import re; import os; import parsel; 1.請求網頁 header = { "user-agent":'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_5) AppleWebKit/537. ...