物件
1. 物件:使用基本資料型別的資料,創建的變數都是獨立的,不能成為一個整體
物件屬于一個復合資料型別,在物件中可以保存多個不同資料型別的屬性,
物件的分類:
(1)內建物件:由ES標準中定義的物件,在任何的ES的實作中都可以使用(Math,string,number)
(2)宿主物件:由JS的運行環境提供的物件,目前來說主要指由瀏覽器提供的物件(BOM)
(3)自定義物件:由開發人員自己創建的物件
2. 創建物件
使用new關鍵字呼叫的函式,是建構式constructor
建構式是專門用來創建物件的函式
在物件中保存的值稱為屬性,向物件添加屬性
語法:物件.屬性名=屬性值;
向obj中添加一個name/gender/age屬性
Obj.name=”孫悟空”;obj.gender=”男”;obj.age=18;
讀取物件中的屬性
語法:物件.屬性名
console.log(obj.gender);
var obj=new Object();
obj.name="孫悟空";
obj.age=18;
obj.gender="男";
console.log(obj.name);
修改物件屬性值
語法:物件.屬性名=新值;
洗掉物件的屬性
語法:delete 物件.屬性名
delete obj.age
物件的屬性名不強制要求準守識別符號的規范,任何名字都可以
obj.var=”hello”;
如果要使用特殊的屬性名,不能采用.的方式來操作,需要使用另一種方式
語法:物件[“屬性名”]=屬性值
var obj=new Object();
obj["123"]=234;
var n="123";
console.log(obj[n]);
屬性值:JS物件的屬性值,可以是任意的資料型別,也可以是一個物件,
var obj=new Object( );
obj.test="作比較";
var obj2=new Object( );
obj2.name="資訊";
obj.test=obj2;
console.log(obj.test.name);
in 運算子
通過該運算子可以檢查一個物件中是否含有指定的屬性,若有則回傳一個true,沒有回傳false;
語法:“屬性名”in 物件
console.log("test2" in obj);
3. 基本和參考資料型別
基本資料型別(值型別):保存值
string字串;number數值;boolean布林值;null空值;undefined 未定義;
參考資料型別:object物件 保存地址
var obj=new Object();
obj.name="花花";
var obj2=obj;
obj.name="大大"
console.log(obj.name);
console.log(obj2.name);
JS中的變數都是保存到堆疊記憶體中,基本資料型別直接保存在堆疊記憶體中,值與值之間是獨立存在,修改一個變數不會影響其他的變數,
物件保存在堆記憶體中的,每創建一個新的物件,就會在堆記憶體中開辟一個新的空間,而變數保存的是物件的記憶體地址(物件的參考),如果兩個變數保存的是同一個物件參考,當一個通過一個變數修改屬性時,另一個也會受到影響,
|
變數 |
值 |
|
|
|
|
b |
123 |
|
a |
123 |
使用物件字面量來創建一個物件,使用物件字面量,可以創建物件時,直接指定物件中的屬性,
語法:{屬性名:屬性值,屬性名:屬性值,......}
物件字面量的屬性名可以加引號也可以不加,建議不加;但特殊的名字,則必須加引號,
var obj={
name:'豬八戒',
age:18,
gender:'男',
'123':123
};
console.log(obj);
函式function
1. 函式也是一個物件,函式可以封裝一些功能(代碼),在需要時可以執行這些功能(代碼)
創建一個函式物件:
var fun=new Function()
可以將要封裝的代碼以字串的形式傳遞給結構函式,封裝到函式中的代碼不會立即執行,函式中的代碼會在函式呼叫的時候執行,呼叫函式時,函式中封裝的代碼會按照順序執行,
呼叫函式:函式物件() //fun( );
var fun=new Function("console.log('第一個函式')")
fun();
使用函式宣告來創建一個函式
語法:function 函式名([形參1,形參2....形參N]){
陳述句.......
}
function f() {
console.log('第er個函式')
}
f();
使用函式運算式來創建一個函式
var 函式名=function ([形參1,形參2,...形參n]) {
陳述句....
}
2. 函式()中可以指定一個或多個形參,形參之間利用,隔開,宣告形參就相當于在函式內部宣告對應的變數,但不賦值,
在呼叫函式時,可以在()中指定實參,將會賦值給函式中對應的形參,
注意:呼叫函式時決議器不會檢查實參的型別,實參可以是任意的資料型別,
呼叫函式時,決議器也不會檢查實參的數量,多余實參不會被賦值,若實參的數量少于形參的數量,則沒有對應實參的形參將是undefined
3. 回傳值
可以使用return來設定函式的回傳值
語法:return 值
var sum=function (a,b) {
var c=a+b;
return c;}
sum(3,5);
return后的值將會作為函式的執行結果回傳,可以定義一個變數,來接收該結果
var sum=function (a,b) {
var c=a+b;
return c;}
var result=sum(3,5);
console.log(result);
4. 回傳值的型別
回傳值可以是任意型別:物件,數值,函式.....
function fun1() {
return {name:'黎明'};}
var a=fun1();
console.log('a='+a.name);
嵌套函式:fun2函式在fun1內,fun1呼叫fun2,外部執行fun1,就會呼叫fun2
function fun1() {
function fun2() {
alert('我是fun2')}
fun2();}
fun1();//a=fun1();console.log(a);//a();//fun1()();
5. 立即執行函式
函式定義之后立即被執行,往往只會執行一次,
(function () {
alert('這是一個匿名函式');
})();
6. 方法
函式也可以稱為物件的屬性,一個函式作為物件的屬性保存,該函式稱為這個物件的方法,呼叫函式就是呼叫物件的方法,-----封裝在物件中的函式叫方法
var obj=new Object();
obj.name='小明';
obj.sayName=function () {
console.log(obj.name);};
obj.sayName();
7. 列舉物件中的屬性
使用for....in陳述句
語法:
for(var 變數 in 物件){
console.log(‘hello’);} //出現幾次就執行幾次
每次執行時,會將物件中的一個屬性的名字賦值給變數
var obj=new Object();
obj.name='小李';
obj.age=43;
obj.gender='男';
obj.address='華夏小區';
for(var n in obj){
console.log(n);屬性名} //console.log(obj[n]);屬性值
8. 作用域
一個變數的作用范圍:
全域作用域:直接撰寫在script標簽中的JS代碼,在頁面打開時創建,在頁面關閉時銷毀,在全域作用域中有一個全域物件window,代表一個瀏覽器的視窗,由瀏覽器創建可直接使用,
創建的變數都可以作為window物件的屬性保存;創建的函式都會作為window物件的方法保存,
全域變數,在頁面任意的部分都可以訪問,
var a=10;
console.log(window.a);
變數宣告提前:使用var關鍵字宣告的變數,會在所有代碼執行之前被宣告,不會賦值
console.log(a);
var a=10; //不會報錯,但a=10會報錯
函式宣告提前:使用函式宣告形式創建的函式function函式(){},會在所有代碼執行之前被創建,所以可以在函式宣告前來呼叫,
使用函式運算式創建的函式,不會被宣告提前,所以不能在宣告前呼叫,
fun(); //會被執行!!
fun2(); //不會被執行!!
function fun() {
console.log('我是一個fun函式');}
var fun2=function () {
console.log('我是一個fun2函式')}
函式作用域:呼叫函式時創建函式作用域,函式執行完畢以后,函式作用域銷毀,每呼叫一次函式就會創建一個新的函式作用域,之間相互獨立,
函式作用域中可以訪問到全域變數,全域作用域無法訪問到函式作用域的變數,在函式作用域操作一個變數時,會先在自身作用域中尋找,若有直接使用,若沒有則向上一級作用域中尋找,直到找到全域作用域,若沒有就會報錯,
在函式作用域也會有宣告提前的特性,使用var關鍵字宣告的變數,會在函式中所有的代碼執行之前被宣告,
函式中,不適用var宣告的變數都會變成全域變數,
var c=10;
function fun1() { //fun1(c) 定義形參=在函式作用域中宣告變數
console.log(c);
c=10; //var c=10結果為undefined
}
fun1();
9. debug
F12-->腳本-->斷點
2. this
決議器在呼叫函式每次都會向函式內部傳遞進一個隱含的函式this,this指向的是一個物件,根據函式的呼叫方式的不同,this會指向不同的物件,
誰呼叫函式,this就會指向誰;
1. 函式方式呼叫,this指向window
function fun() {
console.log(this);
}
fun(); //結果為windo
2. 以方法形式呼叫時,this就是呼叫方法的物件
function fun() {console.log(this);}
var obj={name:'小明',
sayName:fun};
obj.sayName(); //結果為物件obj
3.以建構式的形式呼叫時,this就是新創建的那個物件
根據呼叫者的不同呼叫:
var name='全域';
function fun() { console.log(this.name);} //不用this只會顯示’全域’
var obj1={ name:'小明',
sayName:fun};
var obj2={ name:'花花',
sayName:fun};
obj2.sayName();
11. 使用工廠方法創建物件
通過該方法大批量的創建物件,將公共代碼寫成一個函式,不用重復寫代碼
缺點:創建物件都是object這個型別,導致無法區分多種不同型別的物件,
代碼:
function createPerson(name,age,gender) {
// 創建一個新的物件
var obj=new Object();
// 向物件中添加屬性
obj.name=name;
obj.age=age;
obj.gender=gender;
obj.sayName=function () {
console.log(this.name); }
// 將新的物件回傳
return obj;}
var obj1=createPerson('小敏',13,'男');
obj1.sayName();
12. 建構式 加new
創建一個建構式,專門來創建Person物件,建構式是一個普通的函式,創建方式和普通函式沒有區別,不同的是建構式習慣上首字母大寫
區別:建構式和普通函式的區別就是呼叫方式不同,普通函式直接呼叫,建構式需要使用new關鍵字來呼叫,
建構式的執行流程:
- 立刻創建一個新的物件
- 將新建的物件設定為函式中this,在建構式中可以使用this來參考新建的物件
- 逐行執行函式中的代碼
- 將新建的物件作為回傳值回傳
普通函式:
function Person() {}
var per=Person(); //結果為undefined
建構式:
function Person() { alert(this);}
var per=new Person();
console.log(per); //結果為 object
例如:(類)
function Person(name,age,gender) {
this.name=name;
this.age=age;
this.gender=gender;
this.sayName=function () {
alert(this.name);
}
}
var per=new Person('花花',12,'男');
console.log(per);

使用instanceof可以檢查一個物件是否是一個類的實體
語法:物件 instanceof 建構式 (per instanceof Person)
如果是,則回傳true,否則回傳false
代碼:
console.log(per instanceof Person);
console.log(dog instanceof Person);
所有的物件都是object的后代,所以任何物件和Object做instanceof檢查時會被回傳true
console.log(per instanceof Object);
13. 建構式的修改
創建一個Person建構式:在Person建構式中,為每一個物件都添加一個sayName方法,目前的方法是在建構式內部創建的,所以建構式每次執行都會創建一個新的sayName方法,每一個建構式sayName都是唯一的,
解決方法:
1.將sayName方法在全域作用域中定義
代碼:
function Person(name,age,gender) {
this.name=name;
this.age=age;
this.gender=gender;
this.sayName=fun;}
function fun() {
alert(this.name);}
但是將函式定義在全域作用域,污染了全域作用域的命名空間,而且很不安全
2. 原型prototype:創建的每一個函式,決議器都會向函式中添加一個屬性prototype;
該屬性對應一個物件,這個物件就是原型物件
如果函式作為普通函式呼叫prototype沒有任何作用;當函式以建構式的形式呼叫時,它所構建的物件中都會有一個隱含的屬性,指向該建構式的原型物件,可通過__proto__來訪問該屬性,

原型物件==一個公共區域,所有同一個類的實體都可以訪問到這個原型物件,可以將物件中共有的內容,統一設定到原型物件中,
當訪問物件的一個屬性或方法時,它會先在物件自身中尋找,若有則直接使用,
代碼:
function Person() { }
// 向Person的原型中添加屬性a
Person.prototype.a=123;
//向Person的原型中添加一個方法
Person.prototype.sayHello=function () {
alert('hello');}
var mc1=new Person();
var mc2=new Person();
mc1.a='我是mc中的a';
console.log(mc1.a); //先在mc1中尋找,有,a='我是mc中的a';
console.log(mc2.a); //mc中未找到,在原型物件中尋找a=123;
mc2.sayHello();
14. 原型物件
使用in檢查物件中是否含有某個屬性時,若物件中沒有但原型中有,回傳true,
使用物件的hasOwnProperty()來檢查物件中是否含有該屬性,使用該方法只有當物件自身含有屬性時,才會回傳true,
代碼:
function MyClass() {}使用物件的hasOwnProperty()來檢查物件中是否含有該屬性
MyClass.prototype.name='我是原型中的名字';
var mc=new MyClass();
//使用in檢查物件中是否含有某個屬性時,若物件中沒有但原型中有,回傳true
// console.log('name' in mc);
//使用物件的hasOwnProperty()來檢查物件中是否含有該屬性
mc.a=123;
console.log(mc.hasOwnProperty('name')); //結果false
console.log(mc.hasOwnProperty('a')); //結果true
15. 原型物件也是物件,所以它也有原型,當使用一個物件的屬性或方法時,會先在自身中尋找,自身有則直接使用,若沒有則去原型物件中尋找,若原型物件中有就使用,若沒有則去原型的原型中尋找,直到找到Object物件的原型,Object對象的原型沒有原型,如果在Object中依然沒有找到,則回傳undefined

console.log(mc.__proto__.__proto__.hasOwnProperty('hasOwnProperty'))
16. toString( )
在頁面上列印一個物件時,實際上輸出的物件的toString()方法的回傳值,若希望在輸出物件時不輸出[object object],可以為物件添加一個toString( )方法,
代碼:
function Person(name,age,gender){
this.name=name;
this.age=age;
this.gender=gender;}
Person.prototype.toString=function () {
return '我是一個小per';}
var per=new Person('孫悟空',14,'男');
var per1=new Person('孫空',14,'男');
var result=per.toString();
// console.log('result='+result);
console.log(per1);
17. 垃圾回收(GC)
當一個物件沒有任何的變數或屬性對它進行參考,此時將永遠無法操作該物件,這種物件就是一個垃圾,這種物件過多會占用大量的記憶體空間,導致程式運行交換,需要進行清理,
在JS中擁有自動的垃圾回識訓制,會自動將這些垃圾物件從記憶體中銷毀,不需要也不能進行垃圾回收操作,需要將不再用的物件設定為null

var obj=new Object();
obj=null;
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/7213.html
標籤:JavaScript
