javascripts面向?qū)ο蠡A(chǔ)

js中對(duì)象的分類

對(duì)象的分類:

1.內(nèi)置對(duì)象:由ECMA實(shí)現(xiàn) 的,不依賴于宿主環(huán)境的對(duì)象,這些對(duì)象在js程序執(zhí)行之前就已經(jīng)存在了。
本地對(duì)象:Object,Array,String,Number,Boolean,Date等。
單體內(nèi)置對(duì)象:只有兩個(gè)Global,Math。與本地對(duì)象的區(qū)別在于:不需要加new 。
2.宿主對(duì)象:就是js寄宿環(huán)境定義的對(duì)象。
在瀏覽器端的js而言,宿主對(duì)象就是瀏覽器對(duì)象。例如:window,document,history等。
Global對(duì)象:定義的全局變量,全局函數(shù),其實(shí)就是這個(gè)對(duì)象的屬性。
其它的本地對(duì)象其實(shí)也是它的屬性。從這個(gè)意義上講,Global東西相當(dāng)于是js程序運(yùn)行總管。
3.自定義的對(duì)象

window對(duì)象

window是Global對(duì)象在瀏覽器端的代言人。換句話說,在瀏覽器端編寫js程序,就直接可以使用window來代替global。(如果你在你服務(wù)器端,在node.js中g(shù)lobal對(duì)象是真實(shí)存在的)。
定義的任何全局變量,函數(shù),都是window對(duì)象的屬性。

var  a = 1,
     b = 2;
console.log(window.a)  //1
console.log(window.b)  //2

但是在使用中window可以省略。

js的三條定律

一切都是對(duì)象
1.基本數(shù)據(jù)類型也當(dāng)作對(duì)象處理
var  string = 'dabao';
console.log(string.length);

string為基本數(shù)據(jù)類型,但是他同樣有方法,在運(yùn)行過程中js會(huì)把它臨時(shí)轉(zhuǎn)變成一個(gè)包裝類的對(duì)象。

var string = new String('dabao')
2.引用類型的數(shù)據(jù)也是對(duì)象

函數(shù):

function  f(){}
console.log(f);
console.log(f instanceof  Object)  //true
Paste_Image.png

數(shù)組:
給數(shù)組添加新屬性,一定要按下標(biāo)的序號(hào)規(guī)則去加,如果下標(biāo)是字符串(正確的下標(biāo)應(yīng)該是數(shù)字),則length的值不會(huì)增加,但,添加的屬性確定是添加成功。

var a = [1,2,3];
a.name = 'dabao';
a[3] = 'xiaobao';
Paste_Image.png

對(duì)象自然也是對(duì)象。

屬性操作

四個(gè)特征:
configurable:是否可以刪除。默認(rèn)為true。
writable:是否可以修改屬性的值。默認(rèn)為true。
enumerable:是否可以枚舉。是否可以通過for in 循環(huán)來輸出。默認(rèn)為true。
Value:值。默認(rèn)為undefined。

Object.defineProperty(對(duì)象名,“屬性名”,{
Configurable:
Writable:
Enumerable:
Value:
})

var obj = {}
Object.defineProperty(obj,"name",{
        configurable:false,
        writable:false,
        value:'dabao'
})
console.log(obj)
obj.name = 'xiaobao';
console.log(obj.name)
delete obj.name;
console.log(obj);

Paste_Image.png

函數(shù)被調(diào)用次數(shù)的例子

function f(){
    f.counter++;
}
f.counter = 0;
f();
f();
f();
console.log(f.counter)   //3

深入理解var 與不加var 的區(qū)別

a = 1;
console.log(a);  //1
var b = 2;
console.log(b);  //2
delete a;
delete b;
console.log(window.a);    //undefined
console.log(window.b);   //2

遺漏聲明變量就是window對(duì)象的屬性,是可以被刪除的。而加var聲明是不可刪除的。為什么呢?因?yàn)槭褂胿ar添加的屬性有一個(gè)特性是:configurable:true;

對(duì)象是由函數(shù)創(chuàng)造
var array = new Array(1,1)
var f = new Function('x','y','return x+y');
var n = new Number(1)
var obj = new Object();

無論是數(shù)組還是函數(shù)還是基本數(shù)據(jù)類型都是由函數(shù)創(chuàng)建的。

原型與原型鏈

prototype就是原型,__ proto__ 稱為隱式原型。前后有兩個(gè)下劃線。它對(duì)外是隱藏的,我們在程序開發(fā)過程,不會(huì)直接使用它。
1.函數(shù)都有一個(gè)prototype屬性
每個(gè)函數(shù),都會(huì)有很多屬性(因?yàn)楹瘮?shù)也是對(duì)象,而對(duì)象是屬性的集合),其中一定有一個(gè)prototype屬性。
函數(shù)的prototype屬性是一個(gè)對(duì)象,這個(gè)對(duì)象中有很多方法。但是一定有一個(gè)方法:constructor,constructor指向 這個(gè)函數(shù)本身。
(在es6的語法中,使用class創(chuàng)建類,實(shí)際上每個(gè)類都有一個(gè)constructor,即使你不設(shè)置,也會(huì)默認(rèn)存在)
2.每一個(gè)對(duì)象都有一個(gè)__ proto__屬性
對(duì)于函數(shù)而言,也是對(duì)象,所以函數(shù)都會(huì)有一個(gè)prototype和一個(gè)__ proto__屬性。
對(duì)象的__ proto__屬性指向創(chuàng)建這個(gè)對(duì)象的函數(shù)的prototype。

function F(){
    this.name = 'dabao'
}
var f = new F();
console.log(F.prototype)
console.log(f.__ proto__)
Paste_Image.png

如果訪問一個(gè)對(duì)象的屬性時(shí),先在這個(gè)對(duì)象自己的屬性中去找,如果找不到,則沿著__ proto__這個(gè)屬性找,如果__ proto__這個(gè)對(duì)象中還是沒有找到,就在__ proto__對(duì)象的__ proto__屬性中去找,依次下去,這就是原型鏈。
也就是說,當(dāng)我們訪問對(duì)象,會(huì)尋找自己的屬性,當(dāng)找不到自己的屬性時(shí),就去找自己的隱式原型__ proto__,__ proto__指向創(chuàng)建該對(duì)象方法的prototype,prototype實(shí)際上也是一個(gè)對(duì)象,它也有一個(gè)__ proto__這樣會(huì)繼續(xù)往上一級(jí)找。
由于對(duì)象的__ proto__[隱式原型]與創(chuàng)建這個(gè)對(duì)象的函數(shù)(構(gòu)造器)的prototype是一致的。
所以理論上,你對(duì)__ proto__修改會(huì)直接影響prototype。
建議你只使用prototype[原型]

創(chuàng)建對(duì)象
字面量方法
var  obj = {
      name : 'dabao',
      say : function(){
                console.log(this.name)
      }
}

工廠模式

function creatObj(){
         var  obj = {}
         obj.name = 'dabao';
         obj.say = function(){
                 console.log(this.name)   
         }
         return obj;
}
構(gòu)造器模式
function F(){
          this.name = 'dabao'
}
var f = new F()

到底做了什么? 為什么給一個(gè)函數(shù)加一個(gè)new 就能產(chǎn)生對(duì)象呢?
new一共做了如下四件事:
1.創(chuàng)建一個(gè)對(duì)象 var obj = {}
2.F.call(obj);先執(zhí)行F()函數(shù),同時(shí)把this用obj來代替。把F()構(gòu)造器設(shè)置的各種屬性值,直接賦給o.
3.obj.__ proto__ = F.prototype
4.返回 obj;

原型模式
function F(){
    this.name = 'cxh'
}
F.prototpe.say = function(){}

將方法寫在原型上。
注意:不要去修改對(duì)象的__ proto__。會(huì)導(dǎo)致由構(gòu)造器所產(chǎn)生的全部的對(duì)象的屬性都會(huì)受到影響。
覆蓋prototype的問題:
因?yàn)閜rototype里面肯定有一個(gè)contructor方法,假如采用直接覆蓋的方法,將把當(dāng)前的對(duì)象的構(gòu)造器歸置為object。
我們可以采用jq的方法

Paste_Image.png

重新設(shè)置 constructor。

繼承

js特點(diǎn):生來繼承
Var s ={};
s.toString();//為什么有toString()?從__ proto__獲取的。
1.原型繼承

function Parent(){}
function Son(){}
Son.prototype = Parent.prototype
Son.prototype.constructor = Son

2.類式繼承

function Parent(name){
        this.name = name
}

function Son(name,newName){
        this.newName = newName;
        Parent.call(this,name)
}

針對(duì)屬性使用 類式繼承
針對(duì)方法是用原型繼承
使用es6 extends繼承。
繼承方式可以有很多種,但是無論哪種,都是
子類屬性即父類的屬性
子類的方法繼承父類的方法

son.__ proto__ = parent
son.prototype.__ proto__ = parent.prot0type

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容